Find Number of Palindrome Strings in Array Program Errors - c++

I am writing code that finds the number of palindrome strings in a given array of strings. I think I have the right idea, but I am getting weird errors when I run it. What exactly am I doing wrong?
int countPalindromes(string s) {
int size = s.size();
int counter = 0;
string forwardSum = "";
string backwardSum = "";
for(int i = 0; i < size; i++){
for(int j = i; j < size; i++){
forwardSum.push_back(s[j]);
backwardSum.push_back(s[(n - 1)-j]);
if(forwardSum == backwardSum){
counter++;
}
}
}
return counter;
}

string forwardSum[] = {};
This is an array of zero size (which I don't believe is legal but we'll let that pass)
forwardSum[i] = forwardSum[i] + s[j];
This is an attempt to access the ith element of an array which has zero size.
That's bad.
I'm not really following your code (it's late at night), but I think you probably want forwardSum and backwardSum to be strings not arrays of strings. And you probably want to use push_back to add characters from s to those strings. I.e.
string forwardSum;
...
forwardSum.push_back(s[j]); // add s[j] to forwardSum
But if you really do want forwardSum to be an array, then the sensible thing to do would be to use a vector instead.
vector<string> forwardSum(size); // a vector of strings with the given size
Now that should at least not crash with the rest of your code.

Related

How can I copy a string variable to another character by character without defining size of target variable?

I was writing a program where I need to copy a string (length unknown initially) to another string character by character.
I write this code that runs perfectly.
string a = "Hello";
string b( a.length(), 'a');
for (int i = 0; i < a.length(); i++)
b[i] = a[i];
But as the size of the string in C++ is calculated dynamically as
string k = "Hello";
string l = "Hello World";
string m = k;
m = l;
won't give any error. So it is clear that size of a string variable is changing dynamically according to the requirement.
So I tried the same without defining the size of the variable b.
string a = "Hello";
string b;
for (int i = 0; i < a.length(); i++)
b[i] = a[i];
But in this case, my program is crashing and saying String subscript out of range.
Why not in this case the size of variable b is increasing?
What is the cause of the error and how can I achieve this without mentioning the size of any variable?
If you must, you can use push_back:
string a = "Hello";
string b;
for (int i = 0; i < a.length(); i++)
b.push_back(a[i]);
or even1
string a = "Hello";
string b;
for (auto c : a)
b.push_back(c);
But why?
Reference: http://en.cppreference.com/w/cpp/string/basic_string/push_back
1 But don't do this if a is changed in any way: the underlying iterators will be invalidated.
You can simply use the += operator:
for (auto el : a){
b += el;
}
The std::string::operator+= has an overload that accepts character.
Size of the string is dynamic, but it not changed automaticaly as you expect. operator[] only return i-th element, if current size of a string is less than i, it fill fail. It's up to you to make sure size of a string is big enough.
If you couldn't resize string in advance you can query size, increase it by one, ask string to resize, and set last char.
This is how push_back method works

After padding a string with zeroes - it prints unspecified characters? (C++)

Basically, here, I'm trying to reverse an array, and convert the reversed int array into a string (I'm trying to write the equivalent of Java's BigInteger class in C++ - basically turning the input into big endian ordering, breaking down the operations, reversing the result back to little endian format, and returning the string).
And as you can see below, it outputs some strange characters (I think it's an out of range reference?) - but I'm not entirely sure what caused this output?
I would really appreciate if you could take a look at it:
Sample input
int a[] = {1, 2, 3};
int rA[3];
reverseIntArray(a, rA, 3);
string aString = intArrayToString(a, 3);
cout << aString << endl;
Console output
123\216\377
As you can see - it calculates the answer correctly, with the exception of the \277_\377.
I'll post the rest of the relevant functions:
reverseIntArray
void reverseIntArray(int array[], int reversedArray[], int arrayLength) {
for (int i = 0; i < arrayLength; i++) {
reversedArray[i] = array[arrayLength - 1 - i];
}
}
intArrayToString
string intArrayToString(int digits[], int length) {
// convert int array to char array
char digitsChar[length];
for (int i = 0; i < length; i++) {
digitsChar[i] = '0' + digits[i];
}
// convert char array to string
string intString(digitsChar);
return intString;
}
I'm quite sure this is a subtle issue to do with pointers, but I'm still relatively new to C++ (migrating from Java) and I've stared at this for hours but haven't come up with any ideas.
The std::string constructor you are using is assuming that the string you pass is properly terminated, which it isn't and that leads to undefined behavior as the std::string constructor goes beyond the end of the digitsChar array.
Three possible solutions:
Make room for another character in the digitsChar array and terminate it:
char digitsChar[size + 1];
for (...) { ... }
digitsChar[3] = '\0';
string intString(digitsChar);
Use another constructor where you pass the length of the character array:
string intString(digitsChar, length);
Append the characters directly to the string:
string intString;
for (int i = 0; i < length; i++) {
intString += '0' + digits[i];
}
There are of course other solutions as well, like for example using std::ostringstream.

C++ creating a two-dimensional array based on user input string length

I have an assignment to create a block transposition cipher program. A user is to input a phrase of their choice, and the program is to strip the phrase of spaces, punctuation, and make lowercase, before reading its length and creating a two-dimensional array the size of the nearest square that will fit all the chars in the mutated string, and filling in the remaining space with random letters.
Problem is, I'm having issues with creating that square.
I have this so far:
int main()
{
string input;
cout << "Please enter message to cipher." << endl;
getline(cin, input);
/* do punctuation removal/mutation */
int strLength = input.length(); //after mutation
/* need to find the square here before applying sizes and values to arrays */
char * original = new char[][]; // sizes pending
char * transposed = new char[][]; // sizes pending
for (int i = 0; i <= /* size pending */ ; i++)
{
for (int j = 0; j <= /* size pending */ ; j++)
{
transposed[j][i] = original[i][j];
}
}
/* do more stuff here */
}
any ideas?
(I already have done the mutation portion; tested with alternate code)
You can't do e.g.
char * original = new char[][];
First of all you are trying to create an array of arrays (or pointer of pointers) and assign it to a single pointer. You need to do it in two steps:
Allocate the "outer" array:
char **original = new char* [size];
Allocate the "inner" strings:
for (int i = 0; i < size; i++)
original[i] = new char [other_size];
However I would highly recommend against using that! Instead you should be using std::vector instead of "arrays" allocated on the heap, and if the contents are strings then use std::string:
std::vector< std::vector< std::string > > original;
You can take the square root of the length, round down to an integer, and add one to get the new length.
int len = (int)(sqrt(strLength) + 1e-9) + 1;
You'd then malloc the square using len and fill as you normally would.
I believe you do not need the "new" to create your storage. Following code should just do the job:
char buf[size][size]; // size is a variable
... // populate your buf
char tmp;
for(int i = 0; i < size; i++) {
for(int j = 0; j < i; j++) {
tmp = buf[i][j];
buf[i][j] = buf[j][i];
buf[j][i] = tmp;
}
}
This does the transpose in place. You don't need another array to store the char's.

Concatenate ints in an array?

As part of a homework assignment I need to concatenate certain values in an array in C++. So, for example if I have:
int v[] = {0,1,2,3,4}
I may need at some point to concatenate v[1] -> v[4] so that I get an int with the value 1234.
I got it working using stringstream, by appending the values onto the stringstream and then converting back to an integer. However, throughout the program there will eventually be about 3 million different permutations of v[] passed to my toInt() function, and the stringstream seems rather expensive (at least when dealing with that many values). it's working, but very slow and I'm trying to do whatever I can to optimize it.
Is there a more optimal way to concatenate ints in an array in C++? I've done some searching and nearly everywhere seems to just suggest using stringstream (which works, but seems to be slowing my program down a lot).
EDIT: Just clarifying, I do need the result to be an int.
Pseudo code for a simple solution:
int result = 0;
for (int i=0; i < len(v); i++)
{
result = result*10 + v[i];
}
Large arrays will bomb out due to int size overflow.
How about:
int result = (((v[1])*10+v[2])*10+v[3])*10+v[4];
If the number of elements is variable rather than a fixed number, I'm sure you can spot a pattern here that can be applied in a loop.
Remember ASCII codes?
char concat[vSize+1];
concat[vSize] = 0;
for(int i = 0; i < vSize; i++) {
concat[i] = (v[i] % 10) & 0x30;
}
All are integers. Shouldn't you do the following.
//if you want to concatenate v[1] and v[4]
int concatenated;
concatenated = v[1]*10+v[4];
//If you want to concatenate all
concatenated = 0;
for(int i=1;i<=4;i++)
concatenated = concatenated*10+v[i];
the output would be an integer ( not a string)
Things you can do:
Make sure that you compile with -O3 (Or equivalent compiler optimization).
Do you generate the values in the vector yourself? If so, try changing toInt() function to accept a simple pointer type.
Write the conversion yourself (Browser code : may not even compile - u get the idea though):
char* toInt(int* values, size_t length)
{
int *end = values + sizeof(int)*length;
int *cur = values;
char* buf = new char[length + 1]
for(char* out = buf;cur < end;++cur, ++buf)
{
*out = (char)*cur + '0';
}
*buf = '\0';
return buf;
}

String concatenation C++

Given an arbitrary floating point number, say -0.13, suppose we have an algorithm which calculates a binary string of known length L for this number, one by one, from left to right.
(I need to do this computation for calculating the Morton Key ordering for particles(co-orindates given) which in turn in used in building octrees. I am creating
such binary strings for each of x,y,z dimensions)
Is it better/efficient to first create a character array of length L, and then convert this array into a string? i.e.
char ch[L];
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
}
//convert array into string
Or is it better/efficient to start of with a empty string, and then concatenate a new calculated bit into the string on the fly. i.e.
string s = "";
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
s = s + string(ch);
}
Why not do both?
std::string myStr(L);
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
myStr[i] = ch;
}
This creates a std::string with a given size. You then just set each character. This will only work if you can know the size beforehand exactly.
Alternatively, if you want something that is safe, even if you have to add more than L characters:
std::string myStr;
myStr.reserve(L);
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
myStr.push_back(ch);
}
std::string::reserve preallocates the storage, but push_back will allocate more if needs be. If you don't go past L characters, then you will only get the one initial allocation.
Can't you just use a string with a pre-allocated length?
string s(L, '\0');
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
}
I'm not sure I fully understand the conversion happening, but we have objects for a reason. If you use std::string::reserve() first, the performance should be minuscule, and it's obvious what the intent is.
string s;
s.reserve(L);
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
string.push_back(ch);
}
If speed is absolutely necessary, you can instead initialize the string as length L, and bypass length checks:
string s(L,'\0');
for(i = 0; i < L; ++i)
{
// calculation of ch[i]
string[i] = ch;
}
Personally, i am probably out of date, but i use
sprintf ( char * str, const char * format, ... );
to create strings from numbers
sprintf ( outString,"%f", floatingPointNumber);
Use the latter, but also call s.reserve(L) before entering the loop. This is almost as efficient as direct array assignment, but still easier to grok.
EDIT: Other answers suggest using push_back(). Vote for them.
Sidebar: I'm not sure what you are computing, but if you just want to generate a string representation of the number, I'd suggest you simply call sprintf(), or insert the number into a std::stringstream.
If you want the C++ way, use ostringstream. This is generally cleaner code, less error-prone, and easier to read:
float f = ... // whatever you set it to
std::ostringstream s;
s << f;
std::string stringifiedfloat = s.str();
// now you have the float in a string.
Alternately, you can use the C way, sprintf. This is generally more error-prone, and harder to read, but faster performance:
float f = ... // whatever you set it to
char* buffer = new char[L];
sprintf(buffer, "%f", f);
// now you have the float in a string.
Or, you could even use boost's lexical_cast. This has better performance than ostringstream, and better readability than sprintf, but it gives you a dependency on boost:
float f = ... // whatever you set it to
std::string stringified = boost::lexical_cast<std::string>(f);
// now you have the float in a string.