Check to see if a string array value is null/empty C++ - c++

Ok so i want to check to see if the value of the array, array1 is empty and if it is, it should not be put in array2. How do i do this?
for (int i =0; i < 70549; i ++)
{
std::size_t found = array1[i].find(result[1]);
if (found!=std::string::npos)
array2[i] = array1[i];
}
cout

Sounds like you want std::copy_if. I'm not sure what condition you want. In English you describe the C++ function .empty(), but your C++ code implements a test "string contains the substring result[1]". std::copy_if can work with both.

It looks like you want the string's empty() method. You could expand your condition like this:
if (!array1[i].empty() && found != std::string::npos)
array2[i] = array1[i];
Obviously that will leave unchanged (presumably blank) values in array2 though, where the array1 values weren't copied across. If that's not what you want then you'll need to keep a second loop counter which will index array2. It will only be incremented every time you actually copy a value across.

Related

How to print a deque from the end?

Question is quite simple, how do I print a deque, but from behind. Example: I have a deque with elements {5,4,3,2,1}. I want to print that deque, but starting from the last element, so I should have someting like 1 2 3 4 5 on my screen.
Usual for(int i(deque.size()); i > 0; i--) loop obviously won't work.
Little intro to the program. It finds numbers whose sum is even or odd, and sorts them into two different deques that are to be printed on screen.
This is the code that works for 'usual' printing. But my task says to print them backwards.
Oh, and the elements are added to the deque using push_front function. And no, I'm not allowed to use push_back to 'fix' it.
void PrintDek(Dek v4) {
for (int i(0); i < v4.size(); i++) {
std::cout << v4[i];
if (i != v4.size() - 1) std::cout << ",";
}
}
If some of you feel the need for the whole program's code, I'll edit my post.
You can use reverse iterators. See http://en.cppreference.com/w/cpp/container/deque/rbegin.
for(auto iter = deque.rbegin(); iter != deque.rend(); ++iter) {
// do stuff
}
So after seeing my code after a good few hours of sleep (this question was posted after 2AM according to my timezone), I've come to realize what my mistake was. By using deque.size() and moving all the way up to the value that the size() function returns, I was actually going out of range, accessing forbidden parts of memory.
Simple deque.size()-1 now works. So the loop would look like this for(int i(deque.size()-1); i >= 0; i--).

2D Vector - Remove Rows by search

I'm quite new to vector and need some additional help with regards to vector manipulation.
I've currently created a global StringArray Vector that is populated by string values from a text file.
typedef std::vector<std::string> StringArray;
std::vector<StringArray> array1;
I've created a function called "Remove" which takes the input from the user and will eventually compare the input against the first value in the array to see whether it's a match. If it is, the entire row will then deleted and all elements beneath the deleted row will be "shuffled up" a position to fill the game.
The populated array looks like this:
Test1 Test2 Test3
Cat1 Cat2 Cat3
Dog1 Dog2 Dog3
And the remove function looks like this:
void remove()
{
string input;
cout << "Enter the search criteria";
cin >> input;
I know that I will need a loop to iterate through the array and compare each element with the input value and check whether it's a match.
I think this will look like:
for (int i = 0; i < array1.size(); i++)
{
for (int j = 0; j < array1[i].size(); j++)
{
if (array1[i] = input)
**//Remove row code goes here**
}
}
But that's as far as I understand. I'm not really sure A) if that loop is correct and B) how I would go about deleting the entire row (not just the element found). Would I need to copy across the array1 to a temp vector, missing out the specified row, and then copying back across to the array1?
I ultimately want the user to input "Cat1" for example, and then my array1 to end up being:
Test1 Test2 Test3
Dog1 Dog2 Dog3
All help is appreciated. Thank you.
So your loop is almost there. You're correct in using one index i to loop through the outer vector and then using another index j to loop through the inner vectors. You need to use j in order to get a string to compare to the input. Also, you need to use == inside your if statement for comparison.
for (int i = 0; i < array1.size(); i++)
{
for (int j = 0; j < array1[i].size(); j++)
{
if (array1[i][j] == input)
**//Remove row code goes here**
}
}
Then, removing a row is the same as removing any vector element, i.e. calling array1.erase(array1.begin() + i); (see How do I erase an element from std::vector<> by index?)
Use std::list<StringArray> array1;
Erasing an item from an std::vector is less efficient as it has to move all the proceeding data.
The list object will allow you to remove an item (a row) from the list without needing to move the remaining rows up. It is a linked list, so it won't allow random access using a [ ] operator.
You can use explicit loops, but you can also use already implemented loops available in the standard library.
void removeTarget(std::vector<StringArray>& data,
const std::string& target) {
data.erase(
std::remove_if(data.begin(), data.end(),
[&](const StringArray& x) {
return std::find(x.begin(), x.end(), target) != x.end();
}),
data.end());
}
std::find implements a loop to search for an element in a sequence (what you need to see if there is a match) and std::remove_if implements a loop to "filter out" elements that match a specific rule.
Before C++11 standard algorithms were basically unusable because there was no easy way to specify custom code parameters (e.g. comparison functions) and you had to code them separately in the exact form needed by the algorithm.
With C++11 lambdas however now algorithms are more usable and you're not forced to create (and give a reasonable name to) an extra global class just to implement a custom rule of matching.

adding dynamic arrays and removing trailing 0's

I am trying to implement this function to add two dynamic a
rrays, however when I implement this into my main it completely crashes, I have no idea why...
I cannot understand why the program shuts down except the exit code on scite says exit code 255. But that is not helpful. Any idea what the problem may be?
For one:
for (int k=0; k<=max; k++)
This goes out of range. Instead allocate memory for [max+1] elements, since there shall be max+1 terms in the polynomial.
sum = new int[ max + 1 ];
Also, the j loop should start from max.
for (j=max; j>0 && sum[j]==0; --j);
You have a typo on this line:
for (j=max-1; j>0 && sum[j]==0; --j);
^here
The next statement int *tmp=sum; does not get executed.
Also the for loop should probably be
for (j=max-1; j>=0 && sum[j]==0; --j)
^ //don't forget the last member
A couple of nice things about C++ is all the standard containers (like std::vector) and standard algorithms available. For example you could use vectors and backwards iterators and std::find_if_not to find the last non-zero value.
Like
// Create a vector of a specific size, and initialize it
std::vector<int> sum(std::max(a->degree, b->degree), 0);
// Fill it up...
// Find the last non-zero value
auto last_non_zero = std::find_if_not(sum.rbegin(), sum.rend(),
[](const int& value){ return value == 0; });
if (last_non_zero == sum.rbegin())
{
// No zeroes found
}
else if (last_non_zero == sum.rend())
{
// All of it was zero
sum.clear();
}
else
{
std::vector<int> temp(last_non_zero, sum.rend())
std::reverse(temp); // Because the `temp` vector is reversed
sum = temp;
}
After this the vector sum should have been stripped of trailing zeroes.

Working with strcmp and string array

I'm trying to eliminate extra elements in the string array and I wrote the code below. There seems a problem with strcmp function and string arrays. Strcmp doesn't accept the string array elements that way. Can you help me fix that? array3 is string array. I'm coding in C++ and What I want to do is like there are multiple "apple"s or "banana"s in the string array. But I only need one "apple" or one "banana".
for(int l = 0; l<9999; l++)
{
for(int m=l+1;m<10000;m++)
if(!strcmp(array3[l],array3[m]))
{
array3[m]=array3[m+1];
}
}
strcmp returns 0 on equality, so if (strcmp(s1,s2))... means "if the strings are equal then do this...". Is that what you mean?
First of all, you can use operator== to compare strings of std::string type:
std::string a = "asd";
std::string b = "asd";
if(a == b)
{
//do something
}
Second, you have an error in your code, provided 10000 is the size of the array:
array3[m]=array3[m+1];
In this line you are accessing the m+1st element, with m being up to 10000. This means you will eventually try to access the 10001st element, and get out of array bonds.
Finally, your approach is wrong, and this way will not let you remove all the duplicate strings.
A better (but not the best) way to do it is this (pseudocode):
std::string array[];//initial array
std::string result[];//the array without duplicate elements
int resultSize = 0;//The number of unique elements.
bool isUnique = false;//A flag to indicate if the current element is unique.
for( int i = 0; i < array.size; i++ )
{
isUnique = true;//we assume that the element is unique
for( int j = 0; j < result.size; j++ )
{
if( array[i] == result[j] )
{
/*if the result array already contains such an element, it is, obviously,
not unique, and we have no interest in it.*/
isUnique = false;
break;
}
}
//Now, if the isUnique flag is true, which means we didn't find a match in the result array,
//we add the current element into the result array, and increase the count by one.
if( isUnique == true )
{
result[resultSize] = array[i];
resultSize++;
}
}
strcmp works on Cstrings only so if you wanna use it I suggest you alter it to the following: strcmp(array3[l].c_str(),array3[m].c_str()) which makes the strings C Strings.
Another option would be to simply compare them with the equality operator array3[l]==array3[m] this would tell you if the strings are equal or not.
Another way to do what you're trying to do is just to put the array in a set and iterate over it. Sets don't take more than one string of the same content!
References:
More about strcmp :http://en.cppreference.com/w/cpp/string/byte/strcmp
And moreabout c_str: http://en.cppreference.com/w/cpp/string/basic_string/c_str
Regarding String Comparison: http://en.cppreference.com/w/cpp/string/basic_string/compare
C++ Sets http://en.cppreference.com/w/cpp/container/set

dynamically created arrays

My task consists of two parts. First I have to create globbal char array of 100 elements, and insert some text to it using cin. Afterwards calculate amount of chars, and create dedicated array with the length of the inputted text. I was thinking about following solution :
char[100]inputData;
int main()
{
cin >> inputData >> endl;
int length=0;
for(int i=0; i<100; i++)
{
while(inputData[i] == "\0")
{
++count;
}
}
char c = new char[count];
Am I thinking good ?
Second part of the task is to introduce in the first program dynamically created array of pointers to all inserted words. Adding a new word should print all the previous words and if there is no space for next words, size of the inputData array should be increased twice. And to be honest this is a bit too much for me. How I can create pointers to words specifically ? And how can I increase the size of global array without loosing its content ? With some temporary array ?
Regardless of the rest of your question, you appear to have some incorrect ideas about while loops. Let's look at this code.
for(int i=0; i<100; i++) {
while(inputData[i] == "\0") {
++count;
}
}
First, "\0" is not the NUL character. It is a pointer to a string containing only the terminating NUL byte. You want '\0' instead. Assuming this change, there are still problems. Let's work through what will happen:
How does a while loop work? It executes the body repeatedly, as long as the condition is true.
When does a while loop finish? When the condition is finally made false by executing the body.
What's the condition of your loop? inputData[i] == '\0', after correction.
What's the body? ++count.
Can ++count ever change the value of the condition? No, because it doesn't change i.
So, if inputData[i] is not the NUL byte, the while loop never executes.
But, if inputData[i] is the NUL byte, the while loop executes forever.
Assuming you've read a proper string into inputData, then at some point inputData[i] will be NUL, and you'll have an infinite loop.
To count the length of a standard C string, just do this
count = strlen(inputData);
If for some reason you really have to write a loop, then the following works:
int len = 0,
while (inputData[len] != '\0') {
len++;
}
After the loop, len holds the length of the string.
#include <iostream>
#include <string>
int main()
{
std::string input;
std::getline(std::cin, input);
}
Global arrays can't have the size changed dynamically unless they are a pointer to an array, in which case you can erase them and reallocate them.
Perhaps what you're after is an automatically resizing array, like a std::vector. You can see how many letters you have in the array by calling size() on the vector, and you can increase the size of the array by calling resize().
While not the most elegant solution, it might be a bit easier to use for the moment.