how to use substr get string from right hand side in c++ - c++

I have a string of numbers for example 469111252 and I know how to split from left-hand side but how to use substr to split it from right-hand side?
If digitsPerNode = 2
from left 46 91 11 25 2
But I want to get from right 52 12 11 69 4
//left hand side parse
for (int i=0;i<num.length(); i+=digitsPerNode) {
splitNum = num.substr(i,digitsPerNode);
}

Count from top to bottom not from bottom to top.
int numlength=num.length();
if(numlength%2==1)
numlength+=1;
for(int i=numlength;i>=0;i-=digitsPerNode)
{
splitNum = num.substr(i,digitsPerNode);
{

string a = "1234567890-=4";
for (int i = a.length() - 2; i >= -1; i = i - 2)
{
if (i < 0) cout << a.substr(i+1, 1) << endl;
else cout << a.substr(i, 2) << endl;
}

I found the solution with reverse function
DoublyLinkedList::DoublyLinkedList(string value, string dPerNode)
{
digitsPerNode = stoi(dPerNode);
string subString;
reverse(value.begin(), value.end());
for (int i = 0; i <= value.length(); i += digitsPerNode)
{
//cut string by digitsPerNode Ex: 3 500 123 412
subString = value.substr(i, digitsPerNode);
reverse(subString.begin(), subString.end());
insertAtHead(subString);
}
}

Related

translating algorithm for C++ nested while loop diamond pattern

Here is my homework problem for C++:
The following algorithm is a solution to a problem that uses nested loops to display a diamond pattern. Translate the algorithm below in to a C++ program. Build, run and test the program.
Algorithm Solution:
Start
Declare numRows as constant integer = 7
Declare maxPlus as constant integer = 7
Declare numSpaces as integer
Declare numPluses as integer
Declare row as integer
Declare space as integer
Declare plus as integer
Set row = 1
Repeat while row >= 1 AND row <= numRows
Set numPluses = 2 * row - 1
if(numPluses > maxPlus) then
Set numPluses = 14 - numPluses
endif
Set numSpaces = (maxPlus - numPluses) / 2
Set space = 1
Repeat while space >= 1 AND space <= numSpaces
Display( ' ')
Set space = space + 1
End Repeat
Set plus = 1
Repeat while plus >= 1 AND plus <= numPluses
Display( '*')
Set plus = plus + 1
End Repeat
Set row = row + 1
Display a new line
End Repeat
Stop
My code:
#include <iostream>
using namespace std;
int main() {
const int numRows = 7;
const int maxPlus = 7;
int numSpaces;
int numPluses;
int row;
int space;
int plus;
row = 1;
while((row >=1) && (row <= numRows)){
numPluses = 2 * row - 1;
if(numPluses > maxPlus){
numPluses = 14 - numPluses;
}
numSpaces = (maxPlus - numPluses)/ 2;
space = 1;
while((space >= 1) && (space <= numSpaces)){
cout << " ";
space++;
}
while((plus >= 1) && (plus <= numPluses)){
cout << "*";
plus++;
}
row++;
cout << endl;
}
return 0;
}
My question is why am I not getting the diamond pattern? I feel like I translated the algorithm correctly, but all I get is a bunch of blank space. Did I read the problem wrong or did I code wrong? screenshot of C++ code
Before the last while loop:
Set plus = 1
You missed that in your translation.
The code did not initialize plus.
There's a habit that saves much grief. Never declare a variable without giving it a meaningful initial value at the point of definition. Limit the scope of variables to where they are actually used. When translating pseudo-code, that can mean doing a little bit of re-writing. Diggit.
int main() {
const int numRows = 7;
const int maxPlus = 7;
for (int row = 1; row <= numRows; ++row) {
const int trianglePluses = 2 * row - 1;
const int numPluses = trianglePluses <= maxPlus
? trianglePluses
: 2 * numRows - trianglePluses;
const int numSpaces = (maxPlus - numPluses) / 2;
for(int space=1; space <= numSpaces; ++space) {
cout << " ";
}
for (int plus = 1; plus <= numPluses; ++plus) {
cout << "*";
}
cout << endl;
}
return 0;
}

Shifting Objects Up in an Array

I'm creating a program that creates an array of objects in random positions in an array size 8. Once created, I need them to sort so that all the objects in the array are shifted up to the top, so no gaps exist between them. I'm almost there, but I cannot seem to get them to swap to index 0 in the array, and they instead swap to index 1. Any suggestions? (Must be done the way I'm doing it, not with other sorting algorithms or whatnot)
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
struct WordCount {
string name = "";
int count = 0;
};
int main() {
cout << "Original random array: " << endl;
srand(static_cast<int>(time(0)));
int i = 0;
WordCount wordArr[8];
while (i < 4) {
int randomNum = 0 + (rand() % static_cast<int>(7 + 1));
if(wordArr[randomNum].name == "") {
wordArr[randomNum].name = "word" + static_cast<char>(i);
wordArr[randomNum].count = i;
i++;
}
}
int j = 0;
while (j < 8) {
cout << wordArr[j].name << " " << wordArr[j].count << endl;
j++;
}
cout << "\n\nSorted array: " << endl;
for (int i = 7; i >= 0; i--) {
for (int j = 0; j <= 7; j++) {
if (wordArr[i].name != "") {
if (wordArr[j].name == "") {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
}
int k = 0;
while (k < 8) {
cout << wordArr[k].name << " " << wordArr[k].count << endl;
k++;
}
return 0;
}
If I understand your requirement correctly, you want to move all the non-blank entries to the start of the array. To do this, you need an algorithm like this for example:
for i = 0 to 7
if wordArr[i].name is blank
for j = i + 1 to 7
if wordArr[j].name is not blank
swap [i] and [j]
break
So, starting from the beginning, if we encounter a blank entry, we look forward for the next non-blank entry. If we find such an entry, we swap the blank and non-blank entry, then break to loop again looking for the next blank entry.
Note, this isn't the most efficient of solutions, but it will get you started.
Note also I'd replace the 4 and 8 with definitions like:
#define MAX_ENTRIES (8)
#define TO_GENERATE_ENTRIES (4)
Finally:
wordArr[randomNum].name = "word" + static_cast<char>(i);
That will not do what you want it to do; try:
wordArr[randomNum].name = "word" + static_cast<char>('0' + i);
To append the digits, not the byte codes, to the end of the number. Or perhaps, if you have C++11:
wordArr[randomNum].name = "word" + std::to_string(i);
I see couple of problems.
The expression "word" + static_cast<char>(i); doesn't do what you are hoping to do.
It is equivalent to:
char const* w = "word";
char const* p = w + i;
When i is 2, p will be "rd". You need to use std::string("word") + std::to_string(i).
The logic for moving objects with the non-empty names to objects with empty names did not make sense to me. It obviously does not work for you. The following updated version works for me:
for (int i = 0; i <= 7; ++i) {
// If the name of the object at wordArr[i] is not empty, move on to the
// next item in the array. If it is empty, copy the next object that
// has a non-empty name.
if ( wordArr[i].name == "") {
// Start comparing from the object at wordArr[i+1]. There
// is no need to start at wordArr[i]. We know that it is empty.
for (int j = i+1; j <= 7; ++j) {
if (wordArr[j].name != "") {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
}
There was two problems as :
wordArr[randomNum].name = "word" + static_cast<char>(i); this is not what your are looking for, if you want that your names generate correctly you need something like this :
wordArr[randomNum].name = "word " + std::to_string(i);
Your sorting loop does not do what you want, it's just check for the "gaps" as you said, you need something like this :
for (int i = 0; i < 8; ++i) {
for (int j = i+1; j < 8; ++j) {
if (wordArr[i].name == "" || (wordArr[i].count < wordArr[j].count)) {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
}
}
}
Your algorithm sorts the array, but then looses the sorting again.
You want to swap elements only when i > j, in order to push elements to the top only. As a result, you need to change this:
if (wordArr[j].name == "")
to this:
if (wordArr[j].name == "" && i > j)
Consider this array example:
0
ord 1
0
0
rd 2
word 0
d 3
0
Your code will sort it to:
d 3
ord 1
word 0
rd 2
0
0
0
0
but when i = 3, it will try to populate the 5th cell, and it will swap it with rd 2, which is not what we want.
This will push rd 2 down, but we don't want that, we want gaps (zeroes) to go to the end of the array, thus we need to swap eleemnts only when they are going to go higher, not lower, which is equivalent to say when i > j.
PS: If you are a beginner skip that part.
You can optimize the inner loop by using one if statement and a break keyword, like this:
for (int j = 0; j <= 7; j++) {
if (wordArr[i].name != "" && wordArr[j].name == "" && i > j) {
WordCount temp = wordArr[i];
wordArr[i] = wordArr[j];
wordArr[j] = temp;
break;
}
}

Pattern Printing-Where am I going wrong in this C++ code?

I wrote a program to print a N x N square pattern with alternate 0's and 1's. For eg. A 5 x 5 square would looks like this:
I used the following code-
#include<iostream.h>
int main()
{
int i, n;
cin >> n; //number of rows (and columns) in the n x n matrix
for(i = 1; i <= n*n; i++)
{
cout << " " << i%2;
if(i%n == 0)
cout << "\n";
}
fflush(stdin);
getchar();
return 0;
}
This code works fine for odd numbers but for even numbers it prints the same thing in each new line and not alternate pattern.For 4 it prints this-
Where am I going wrong?
In my opinion the best way to iterate over matrix is using loop in another loop.
I think this code will be helpful for you:
for(i = 0; i < n; i++) {
for (j = 1; j <= n; j++) {
cout<<" "<< (j + i) % 2;
}
cout<<"\n";
}
where n is number of rows, i and j are ints.
Try to understand why and how it works.
If you're a beginner programmer, then I suggest (no offence) not trying to be too clever with your methodology; the main reason why your code is not working is (apart from various syntax errors) a logic error - as pointed out by blauerschluessel.
Just use two loops, one for rows and one for columns:
for (int row = 1; row <= n; row++)
{
for (int col = 0; col < n; col++)
cout << " " << ((row % 2) ^ (col % 2));
cout << "\n";
}
EDIT: since you wanted a one-loop solution, a good way to do so would be to set a flip flag which handles the difference between even and odd n:
bool flip = false;
int nsq = n * n;
for (int i = 1; i <= nsq; i++)
{
cout << " " << (flip ^ (i % 2));
if (i % n == 0) {
if (n % 2 == 0) flip = !flip;
cout << "\n";
}
}
The reason that it isn't working and creating is because of your logic. To fix this you need to change what the code does. The easiest way to handle that is to think of what it does and compare that to what you want it to do. This sounds like it is for an assignment so we could give you the answer but then you would get nothing from our help so I've writen this answer to guide you to the logic of solving it yourself.
Lets start with what it does.
Currently it is going to print 0 or 1 n*n times. You have a counter named i that will increment every time starting from 0 and going to (n*n)-1. If you were to print this number i you would get the following table for n=5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Now you currently check if the value i is odd or even i%2 and this makes the value 0 or 1. Giving you the following table
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
Now in the case of n=4 your counter i would print out to give you a table
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Now if you print out the odd or even pattern you get
1 0 1 0
1 0 1 0
1 0 1 0
1 0 1 0
This pattern diffrence is because of the changing pattern of printed numbers due to the shape of the square or more accurately matrix you are printing. To fix this you need to adjust the logic of how you determine which number to print because it will only work for matrixes that have odd widths.
You just need to add one more parameter to print the value. Below mentioned code has the updated for loop which you are using:
int num = 0;
for(i = 1; i <= n*n; i++)
{
num = !num;
std::cout << " " << num;
if(i%n == 0) {
std::cout << "\n";
num = n%2 ? num : !num;
}
}
The complete compiled code :
#include <iostream>
#include <stdio.h>
int main()
{
int i, n, num = 0;
std::cin >> n; //number of rows (and columns) in the n x n matrix
for(i = 1; i <= n*n; i++)
{
num = !num;
std::cout << " " << num;
if(i%n == 0) {
std::cout << "\n";
num = n%2 ? num : !num;
}
}
fflush(stdin);
getchar();
return 0;
}

Generating substrings in c++

I'm trying to generate all the substrings of the word fun.
But it prints "un" two times, I don't know why.
int c, i;
string s = "fun";
for (c = 0; c < s.length(); c++)
{
for (i = c+1; i <= s.length(); i++)
{
string d = s.substr(c, i);
cout << d << endl;
}
}
The second parameter to substr is length, not the ending index of the sub-string.
You can use the following logic to get all sub-strings:
Start from index 0, select the substring of length 1, then of length 2, then 3 and so on
Then move on to index 1 and perform the same to it and so on. (When at index 1, the remaining length of the string would be 2, in case of fun, so we'd have to run the loop till length 2)
string s = "fun";
for (int c = 0; c < s.length(); c++)
{
for (int i = 1; i <= s.length() - c; i++)
{
string d = s.substr(c, i);
cout << d << endl;
}
}
But it prints "un" two times, I don't know why.
you can find why if you print c and i
...
for (i = c+1; i <= s.length(); i++)
{
cout << "c,i: " << c << i << endl; // add this line to debug !
string d = s.substr(c, i);
...
the output:
c,i: 01
f
c,i: 02
fu
c,i: 03
fun
c,i: 12
un
c,i: 13
un
c,i: 23
n
Note that, substr will just add as many char as possible after c, if i is longer than the remaining characters in your string, as per http://www.cplusplus.com/reference/string/string/substr/
Number of characters to include in the substring (if the string is shorter, as many characters as possible are used).

Xcode gives different results every time I run C++ tests

I am working on a program that receives a char array. In that char array are numbers separated by spaces. The program is supposed to receive a number and add that number's palindrome to itself. If the result is not a palindrome, then we are supposed to add the result's palindrome to the result and so on until a result is a palindrome. For example, if the char array is "195", then 195 + 591 = 786. 786 is not a palindrome, so 786 + 687 = 1473. 1473 + 3741 = 5214. Finally 5214 + 4125 = 9339, which is a palindrome, so this is the answer. Then, the program should return the number of additions it ran to get the answer, followed by the answer. In this example, the program would return "4 9339".
My program works (as far as I can tell,) but for whatever reason, whenever I run Xcode, it returns different results. For example, one time I ran it everything was fine except for case 7. The next time I ran it, every single test failed. If I ran it again, every case would work except for 7 and 9. Does anybody know why this is happening? Below is all of my code, including the test cases that Xcode is running. I also tried commenting what is occurring in the program.
I would appreciate anybody's help! I am an amateur when it comes to C++, so it might be something trivial I am overlooking, or it could be something more advanced--I'm honestly not really sure. Thank you to everybody in advance!
EDIT: I have used Xcode's debugger and nothing fails or looks out of place when I do it that way, which makes it only more mysterious as to why it fails when I run the tests without debugging.
EDIT 2: Then test cases were provided by my professor, not myself.
#include <iostream>
#include <string>
using namespace std;
//returns the reverse of a number
unsigned long reverse(unsigned long n) {
unsigned long reverse = 0;
while(n != 0) {
unsigned long remainder = n%10;
reverse = reverse*10 + remainder;
n /= 10;
}
return reverse;
}
//return what the palindrome result is
string palindrome(string numberInString, int &counter) {
counter++;
//convert input, which is a string, to int
unsigned long number = std::stol(numberInString);
//reverse number and assign it to numberReversed
unsigned long numberReversed = reverse(number);
//add the number and its reverse
unsigned long result = number + numberReversed;
//reverse the result and assign it to resultReversed
unsigned long resultReversed = reverse(result);
//check to see if result and its reverse are equal; otherwise, keep going until they are
while (result != resultReversed) {
counter++;
//reassign number as result
number = result;
//reverse number and assign it to numberReversed
numberReversed = reverse(number);
//add the number and its reverse
result = number + numberReversed;
//reverse the result and assign it to resultReversed
resultReversed = reverse(result);
}
//return result
return std::to_string(result);
}
//the "main" method
char* find(const char* array) {
//instatntite counter, which will be used later
int counter = 0;
//instantiate result string, which is what we are returning
string result = "";
int i = 0;
//will be used to construct int being checked as a palindrome
string currentNumberConstruction = "";
//go through array until end of array
while (array[i] != '\0') {
//if find a space
if (array[i] == ' ') {
//call palindrome function and add it to result later on
string palindromeNumber = palindrome(currentNumberConstruction, counter);
result += std::to_string(counter);
//add to result how many cycles until palindrome found
result += " " + palindromeNumber + " ";
//reset counter (how many cycles until palindrome found)
counter = 0;
//reset currentNumberConstruction (int being checked as a palindrome)
currentNumberConstruction = "";
//continue through array
i++;
} else {
//add char checked to currentNumberConstruction (int being checked as a palindrome)
currentNumberConstruction += array[i];
//continue through array
i++;
}
}
if (currentNumberConstruction != "") {
string palindromeNumber = palindrome(currentNumberConstruction, counter);
result += std::to_string(counter);
result += " " + palindromeNumber;
counter = 0;
currentNumberConstruction = "";
i++;
}
//convert result from string to char*
char* realResult = new char[result.length()];
for (unsigned int j = 0; j < result.length(); j++) {
realResult[j] = result[j];
}
//return char* realResult
return realResult;
}
int main() {
const char* array = NULL;
const char* expected = 0;
for (int i = 0; i < 10; i++) {
switch (i) {
case 0:
array = "195 265 750";
expected = "4 9339 5 45254 3 6666";
break;
case 1:
array = "2 99 4000000000 20 100 1";
expected = "1 4 6 79497 1 4000000004 1 22 1 101 1 2";
break;
case 2:
array = "79 88 97 99";
expected = "6 44044 6 44044 6 44044 6 79497";
break;
case 3:
array = "157 158 166 167 175 188 193 197";
expected = "3 8888 3 11011 5 45254 11 88555588 4 9559 7 233332 8 233332 7 881188";
break;
case 4:
array = "266 273 274 292 365";
expected = "11 88555588 4 5115 4 9559 8 233332 11 88555588";
break;
case 5:
array = "1089 1091 1099";
expected = "4 79497 1 2992 2 11011";
break;
case 6:
array = "19991 2914560 12345678";
expected = "8 16699661 5 47977974 1 99999999";
break;
case 7:
array = "777";
expected = "4 23232";
break;
case 8:
array = "130031 9";
expected = "1 260062 2 99";
break;
case 9:
array = "1234567890123456789";
expected = "2 12222222211222222221";
break;
default:
cout << "we should never get here" << endl;
return -1;
}
char* actual = find(array);
bool equal = strcmp(expected, actual) == 0;
cout << "test " << (i + 1) << ": " << (equal ? "ok" : "failed");
if (!equal) {
cout << " expected [" << expected << "] but was [" << actual << "]";
}
cout << endl;
delete actual;
}
return EXIT_SUCCESS;
}
Your problem is here:
char* array = NULL;
You don't actually allocate any memory to store the array, you need to initialize this in a way that gives it some memory. Otherwise you are just picking random memory in the system and you will probably get a SegFault eventually.
This could be done like this:
char array[100];
or you could use std::string instead. This creates a character array with 100 characters to use, you can adjust the size to your need.
Not sure if it's the only mistake but you don't null terminate result:
char* realResult = new char[result.length()];
Should be:
char* realResult = new char[result.length()+1];
realResult [result.length()] = 0;
Otherwise the behaviour could be very random.