is String or is Number function - qt

I'm actually working on a personal "Excel" for school.
When the value of my cell is a number (int), I want to add it in my listNumber (QList int). When the value of my cell is a String, I want to add it my listString.
These two lists then allow me to sort.
The problem is here :
QString test = text(i, j);
test.toInt(&ok);
if (ok == true) {
listNumber.append(test.toInt());
qSort(listNumber.begin(), listNumber.end());
}
ERROR ASSERT failure in QList<T>::at: "index out of range" .
I think it's because it wants to "insert" a string in a list of integer.
Here my function "sort"
QList<QString> listString;
QList<int> listNumber;
bool ok;
QTableWidgetSelectionRange range = selectedRange();
for (int j = range.leftColumn(); j <= range.rightColumn(); ++j) {
for (int i = range.topRow(); i <= range.bottomRow(); ++i) {
QString test = text(i, j);
test.toInt(&ok);
if (ok == true) {
listNumber.append(test.toInt());
qSort(listNumber.begin(), listNumber.end());
}
}
}
if (listNumber.count() == 0) {
QMessageBox test;
test.setText("liste vide");
test.exec();
}
else {
int x = 0;
for (int j = range.leftColumn(); j <= range.rightColumn(); ++j) {
for (int i = range.topRow(); i <= range.bottomRow(); ++i) {
Spreadsheet::setFormula(i, j, QString::number(listNumber.at(x)));
x++;
}
}
}
Thank you a lot for your help.

First of all, qSort in Qt is deprecated and it is recommended not to use it:
QT_DEPRECATED_X("Use std::sort") inline void qSort(...
You can use std::sort instead:
#include <algorithm>
//...
std::sort(listNumber.begin(), listNumber.end(), std::less<int>());
//or simply:
std::sort(listNumber.begin(), listNumber.end()); // using default comparison (operator <)
(But also you can simply call deprecated qSort:)
qSort(listNumber);

Related

Why is erase function giving a runtime error?

vector<int> a;
a.push_back(0);
int n = a.size();
int cnt = 0;
for (auto itr = a.begin(); itr != a.end(); itr++)
{
if(*itr == 0)
{
cnt++;
a.erase(itr);
}
}
The code is working on inserting numbers other than zero.
The line a.erase(itr) is giving a runtime error for some reason.
Please help.
with erase you modify the vector so the iterator become invalid, a solution modifying a little your code :
vector<int> a;
a.push_back(0);
int n=a.size();
int cnt=0;
auto itr=a.begin();
while (itr != a.end())
{
if(*itr == 0)
{
cnt++;
itr = a.erase(itr);
}
else
++itr;
}
Note the right type for n and count is size_type rather than int

Firebase (....ContinueWith(task => ...) in a For-Loop

First, this is the code:
for (int j = 1; j <= count; j++)
{
db.Child("Some Child").GetValueAsync().ContinueWith(task =>
{
Debug.Log("j: " + j); // Here the Debug will show me that j = count
if (task.IsFaulted)
{
// ERROR HANDLER
}
else if (task.IsCompleted)
{
// Some Code Here
}
});
}
Ok, so my problem is that after the "....ContinueWith(task => ..." ' j ' will become directly equal to the count variable. Why this happens and how to solve it? Or is there another method to do that?
Ok, so my problem is that after the "....ContinueWith(task => ..." ' j
' will become directly equal to the count variable. Why this happens
and how to solve it?
That's because you used <= instead of <. With <=, j must be equals to count for the loop condition to be met and finish. If you want j to be less than count then use count-1 or simply use <.
So, that should be
for (int j = 1; i <= count-1; j++)
Or
for (int j = 1; i < count; j++)
Note that array starts from 0 not 1 so int j = 1; should be int j = 0; but I have a feeling that's what you wanted to do and you are starting the loop from 1 on purpose.
Finally, another problem is your variable being captured in a loop because you are using lambda in the ContinueWith function. See this post for more information. To use the j variable inside the ContinueWith lambda function, make a copy of it then use that copy instead of the j variable.
db.Child("Some Child").GetValueAsync().ContinueWith(task =>
{
//MAKE A COPY OF IT
int jCopy = j;
Debug.Log("j: " + jCopy); // Here the Debug will show me that j = count
}
Complete fixed code:
for (int j = 1; i < count; j++)
{
db.Child("Some Child").GetValueAsync().ContinueWith(task =>
{
//MAKE A COPY OF IT
int jCopy = j;
Debug.Log("j: " + jCopy);
if (task.IsFaulted)
{
// ERROR HANDLER
}
else if (task.IsCompleted)
{
// Some Code Here
}
});
}

Qt - Get numbers in specific area (from QLineEdit)

I have a QTableWidget with some columns and rows and want to add a filter for a particular column.
For that, I've added a QLineEdit in my Window.
I'm already able to filter the rows, when I add only one number in the QLineEdit:
for(int i=0; i<tableWidget->rowCount(); i++)
{
if(!tableWidget->item(i, column)->text().contains(lineEdit->text()))
{
tableWidget->hideRow(i);
}
}
(The slot is connected to the textEdited-Signal of the LineEdit)
What I want to do now:
When I write something like this in the QLineEdit: 10-30; Hide all rows, which doesnt have the number between 10 and 30 (>=10; <=30).
Somebody has an idea, how I can solve this?
This is my decision.
Check if lineEdit text contains two numbers.
QString test = ui->lineEdit->text();
QStringList lst = test.split('-');
if (lst.size() == 2)
Transform they in to integers.
int low = QString(lst[0]).toInt(), high = QString(lst[1]).toInt();
Now let's go to tableWidget and drop in less than or equal to these two numbers.
for (int i = 1; i <= 100; i++) {
int row = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(row);
ui->tableWidget->setItem(row, 0, new QTableWidgetItem(QString::number(i)));
}
connect(ui->lineEdit, &QLineEdit::textChanged, this, [=](const QString &test) {
QStringList lst = test.split('-');
if (lst.size() == 2) {
int low = QString(lst[0]).toInt(), high = QString(lst[1]).toInt();
for (int i = 0; i < ui->tableWidget->rowCount(); i++) {
int temp = ui->tableWidget->item(i, 0)->text().toInt();
if (temp < low || temp > high) {
ui->tableWidget->hideRow(i);
} else {
ui->tableWidget->showRow(i);
}
}
}
});

BFS "Digit Jump" solution working fine on machine, get TLE on online judge

This code is for problem DIGJUMP.
It gives me correct output for all inputs i have tried (i have tried a lot of them). But the problem is that it is getting TLE while submitting it on codechef. I checked the editorial and the same solution (concept-wise) gets accepted, so it means algorithmic approach is correct. I must have something wrong in the implementation.
I tried it for a long time, but could not figure out what is wrong.
#include <string.h>
#include <vector>
#include <queue>
#include <stdio.h>
using namespace std;
class Node
{
public:
int idx, steps;
};
int main()
{
char str[100001];
scanf("%s", str);
int len = strlen(str);
vector<int> adj[10];
for(int i = 0; i < len; i++)
adj[str[i] - '0'].push_back(i);
int idx, chi, size, steps;
Node tmpn;
tmpn.idx = 0;
tmpn.steps = 0;
queue<Node> que;
que.push(tmpn);
bool * visited = new bool[len];
for(int i = 0; i < len; i++)
visited[i] = false;
while(!que.empty())
{
tmpn = que.front();
que.pop();
idx = tmpn.idx;
steps = tmpn.steps;
chi = str[idx] - '0';
if(visited[idx])
continue;
visited[idx] = true;
if(idx == len - 1)
{
printf("%d\n", tmpn.steps);
return 0;
}
if(visited[idx + 1] == false)
{
tmpn.idx = idx + 1;
tmpn.steps = steps + 1;
que.push(tmpn);
}
if(idx > 0 && visited[idx - 1] == false)
{
tmpn.idx = idx - 1;
tmpn.steps = steps + 1;
que.push(tmpn);
}
size = adj[chi].size();
for(int j = 0; j < size; j++)
{
if(visited[adj[chi][j]] == false)
{
tmpn.idx = adj[chi][j];
tmpn.steps = steps + 1;
que.push(tmpn);
}
}
}
return 0;
}
This solution won't finish in acceptable time for the problem. Remember that BFS is O(E). In a string with O(n) digits of some kind there are O(n^2) edges between those digits. For N=10^5 O(N^2) is too much.
This will need some optimizations like if we came to current node from a similar node, we wont skip further to similar nodes.

How can be initialize vector array when 2D array vector is full?

I made dynamic vector class..
But the problem show when main function is looping on and on,
my2dArr's row size is increasing when the function is looping
When data is coming on looping, i want to copy new data..
void main()
{
int data[450];
DynamicArray<int> my2dArr(36, 100);
for(int i = 0;i < 36;++i)
{
for(int j = 1;j < 16;++j)
{
my2dArr[i][j-1] = data[i];
}
}
}
// vector class
class DynamicArray
{
public:
DynamicArray(){};
DynamicArray(int rows, int cols): dArray(rows, vector<T>(cols)){}
vector<T> & operator[](int i)
{
return dArray[i];
}
const vector<T> & operator[] (int i) const
{
return dArray[i];
}
void resize(int rows, int cols)//resize the two dimentional array .
{
dArray.resize(rows);
for(int i = 0;i < rows;++i) dArray[i].resize(cols);
}
void clearCOL()
{
for(int i = 0;i < dArray.size();i++)
{
for(int j = 0;j < dArray[i].size();++j)
{
dArray[j].erase();
}
}
}
private:
vector<vector<T> > dArray;
};
The nested for loop should be fine at Initializing your array, but you'd need to put values into the data array to use it in initializing.
If you're only initializing the data once you might consider a third constructor overload that takes in an int[], like so:
DynamicArray( int rows, int cols, T array[] ): dArray( rows, vector< T >( cols ) )
{
for( int i = 0; i < rows; i++ )
{
for( int j = 0; j < cols; j++ )
{
dArray[i][j] = array[i * rows + j];
}
}
}
You'd need to make sure the array was the size you specified. In your example you pass a 450 int array in to initialize a 3,600 int DynamicArray. In you're example you're actually reading illegal data cause you go to the 16th column of each of the 36 rows so you're actually reading 576 elements from a 450 int array. I suppose the array is uninitialized anyway though, so it's all garbage.

Resources