unexpected value in my code and how I fix it - c++

My assignment:
The teacher has written down the sum of multiple numbers. Pupils should calculate the sum. To make the calculation easier, the sum only contains numbers 1, 2 and 3. Still, that isn't enough for Xenia. She is only beginning to count, so she can calculate a sum only if the summands follow in non-decreasing order. For example, she can't calculate sum 1+3+2+1 but she can calculate sums 1+1+2 and 3+3.
You've got the sum that was written on the board. Rearrange the summons and print the sum in such a way that Xenia can calculate the sum.
Input
The first line contains a non-empty string s — the sum Xenia needs to count. String s contains no spaces. It only contains digits and characters "+". Besides, string s is a correct sum of numbers 1, 2, and 3. String s is at most 100 characters long.
Output
Print the new sum that Xenia can count.
Examples:
Input
3+2+1
Output
1+2+3
Here is my solution:
#include<string>
#include <iostream>
using namespace std;
int main()
{
string su ;
cin >> su;
int n, temp ;
n = su.size();
for (int i = 0 ; i < n ; i+=2)
{
if (su[i]=='1')
{
su[i]-='0';
}
else if (su[i]=='2')
{
su[i]-='0';
}
else if ( su[i]== '3')
{
su[i]-='0';
}
}
for (int i =0 ; i <n ; i+=2)
{
for(int j = 0 ; j< n; j+=2 )
{
if (su[i]< su [j])
{
temp = su[i];
su[i]=su[j];
su[j]=temp;
}
}
}
for(int i = 0 ; i < n ; i++)
{
if(su[i]=='+')
{
cout<<su[i];
}
else
cout<<su[i];//this is the line I can't understand why the result like that;
}
}
the problem is when I run the code with input 3+2+1 i expect the output is 1+2+3+ but I get ?+?+? something like that and I can't understand the reason.

First doing the s[i] -= '0' is very dangerous as it is a string, you should do int myNum = s[i] - '0' instead and then try storing it inside of the string, because when you do s[i] -= '0' it is never casted into an integer, but it stays char all the time so if you do not cast it to integer, it will go ascii code of '1' - '0' okay that is 1, which symbol has an ascii code of one? Oh it's the SOH character... And it takes the SOH character and put it inside of your string, but you string does not know what SOH is so it goes ???..(just joking, strings do not have emotions). All jokes aside the strange behavior is probably caused by you trying to store an illegal character inside a string. I would convert the '1' - '0' to int first.... Then store it in a string.

Related

How to print the string that has lowest ascii sum out of other possibilities

I am writing a program that creates string of length n with x distinct values however it's required that the string created should have lowest ascii sum , my code creates n length string with x distinct values but it doesn't create lowest ascii valued string, help is required what am i doing wrong
int main()
int n,x;
int p= 97;
cin>>n;
cin>>x;
if (n<x || x==1){
cout<< "00";
}
else {
for(int j = 0; j<n ; j++)
{
char ans = (char)(p+(j%x));
cout << ans;
}
}
return 0;
}
If you need to have x distinct characters but need the lowest ASCII value string, you need to make a simple observation: greedily insert as many 'a' as you can (n-x+1, to be precise). Since you need x-1 distinct characters other than 'a', proceed to insert 'b', 'c' and so on, in sequential order.
how about this?
char ans = (char)(p + (j % 26));

I got stuck in this syntax of c++. "Check if the frequency of all the digits in a number is same"

I'm practicing a coding problem on "Check if the frequency of all the digits in a number is same"
#include<bits/stdc++.h>
using namespace std;
// returns true if the number
// passed as the argument
// is a balanced number.
bool isNumBalanced(int N)
{
string st = to_string(N);
bool isBalanced = true;
// frequency array to store
// the frequencies of all
// the digits of the number
int freq[10] = {0};
int i = 0;
int n = st.size();
for (i = 0; i < n; i++)
// store the frequency of
// the current digit
freq[st[i] - '0']++;
for (i = 0; i < 9; i++)
{
// if freq[i] is not
// equal to freq[i + 1] at
// any index 'i' then set
// isBalanced to false
if (freq[i] != freq[i + 1])
isBalanced = false;
}
// return true if
// the string is balanced
if (isBalanced)
return true;
else
return false;
}
// Driver code
int main()
{
int N = 1234567890;
bool flag = isNumBalanced(N);
if (flag)
cout << "YES";
else
cout << "NO";
}
but I can't understand this code:
// store the frequency of
// the current digit
freq[st[i] - '0']++;
How this part actually working and storing frequency?
And instead of this line, what else I can write?
st is a string and thus, a sequence of chars. st[i] is the ith char in this string.
Chars are actually positive integers between 0 and 256, so you can use them with mathematical operations, such as -. These integers are assigned to characters according to the ASCII alphabet. For example: The char 0 is assigned to 48 and the char 7 to 55 (Note: in the following, I use x to denote the character).
Their order makes it possible that mathematical operations are sensible as follows: The char 7 and the char 0 are exactly 7 numbers apart, so 0 + 7 = 48 + 7 = 55 = 7. So: 7 - 0 = 7.
So, you get the position in the freq array according to the number, i.e., the position 0 for 0 or position 7 for 7. The ++ operator increments that value in-place.
This line is several things condensed into one expression
freq[st[i] - '0']++;
The individual part are rather simple and in total it also isn't too difficult:
st[i] - '0' - character digits do not map 1 to 1 to integers. There is an offset. The integer value of '1' is 1 + '0', '2' is 2 + '0'. Hence to get the integer from the digit you need to subtract '0'.
freq[ ... ] - accesses the element of the array. Element at index i stores frequency of digit i.
()++ - increments that frequency by one.
Subtracting the '0' character from the single string character results in the actual number you're looking for. This gives you the number whose frequency you are tracking in your code. This works because of the way characters are stored as ASCII values. Check out the table below. Say that the integer value N that is passed in is 1221. The first value observed in this example is '1' which corresponds to an ASCII value of 49. The ASCII value of '0' is 48. Subtracting the two: 49 - 48 = 1. This allows you to access each integer value individually as part of the array that was the result of the transformation of an 'int' value into a string.
ASCII Table
The code of
for (i = 0; i < n; i++)
// store the frequency of
// the current digit
freq[st[i] - '0']++;
traverses the string and for each item, it subtracts '0', which has a value of 48, because character code 48 represents 0, character code 49 represents 1 and so on.
This code however is superfluos, wastes memory in storing a string and wastes time converting a number to a string. This is better:
bool isNumBalanced(int N)
{
//We create an array of 10 for each digit
int digits[10];
//Initialize the difits
for (int i = 0; i < 10; i++) digits[i] = 0;
//If the input is 0, then we have a trivial case
if (N == 0) return true;
//We loop the digits
do {
//N % 10 is the last digit
//We increment the frequency of that digit
digits[N % 10]++;
} while ((N /= 10) != 0); //We don't stop until we reach the trivial case, see above
//Using the transitivity of equality, we compare all values to the first
//We return false upon the first difference
for (int j = 1; j < 10; j++)
if (digits[0] != digits[j]) return false;
//Otherwise we return true
return true;
}
For those who don't understand it.
int arr[5]={0} // it stores 0 in all places
for(int i=0;i<5;i++){
arr[i]++;
} // Now the array is [1 1 1 1 1]
what happened here is first i=0 then arr[0]++ "here arr[0] value was 0, ++, it increment 0 to 1"
now arr[0] value is 1.
Now `
let
st="1221";
for (i = 0; i < 4; i++) {
freq[st[i] - '0']++;
for i=0, the freq location is : freq[49-48]++ = freq[1]++ means value of freq[1] is 1
for i=1, the freq location is : freq[50-48]++ = freq[2]++ means value of freq[2] is 1
for i=2, the freq location is : freq[50-48]++ = freq[2]++ means value of freq[2] is 2
for i=3, the freq location is : freq[49-48]++ = freq[1]++ means value of freq[1] is 2
ASCII value of '0' is 48
ASCII value of '1' is 49
ASCII value of '2'is 50

Why is there a need to add a '0' to indexes in order to access array values? [duplicate]

This question already has answers here:
What's the real use of using n[c-'0']?
(13 answers)
Closed 2 years ago.
I am confused with this line:
sum += a[s[i] - '0'];
To give some context, this is the rest of the code:
#include <iostream>
using namespace std;
int main() {
int a[5];
for (int i = 1; i <= 4; i++)
cin >> a[i];
string s;
cin >> s;
int sum = 0;
for (int i = 0; i < s.size(); i++)
sum += a[s[i] - '0'];
cout << sum << endl;
return 0;
}
- '0' (or less portable - 48, for ASCII only) is used to manually convert numerical characters to integers through their decimal codes, C++ (and C) guarantees consecutive digits in all encodings.
In EBCDIC, for example, the codes range from 240 for '0' to 249 for '9', this will work fine with - '0', but will fail with - 48). For this reason alone it's best to always use the - '0' notation like you do.
For an ASCII example, if '1''s ASCII code is 49 and '0''s ASCII code is 48, 49 - 48 = 1, or in the recommended format '1' - '0' = 1.
So, as you probably figured out by now, you can convert all the 10 digits from characters using this simple arithmetic, just subtracting '0' and in the other direction you can convert all digits to it's character encoding by adding '0'.
Beyond that there are some other issues in the code:
The array does not start being populated at index 0, but at index 1, so if your string input is, for instance, "10" the sum will be a[1] + a[0], but a[0] has no assigned value, so the behaviour is undefined, you need to wach out for these cases.
for (int i = 0; i < 5; i ++)
cin >> a[i];
would be more appropriate, indexes from 0 to 4, since the array has 5 indexes, if you want input numbers from 1 to 5, you can subract 1 from the to the index later on.
As pointed out in the comment section, a bad input, with alpabetic characters, for instance, will also invoke undefined behaviour.
From the C++ Standard (2.3 Character sets)
... In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
So if you have a character for example '4' then to get value 4 you can write '4' - '0'.
If you will write like for example
sum += a[s[i]];
where i is the character '0' then in fact you will have either
sum += a[s[48]];
if the ASCII coding is used or
sum += a[s[240]];
if the EBCDIC coding is used.
The reversed operation of getting a character from a digit you can write for example
int digit = 4;
char c = digit + '0';
Pay attention to that indices of arrays in C++ start from 0.
Thus this loop
for (int i = 1; i <= 4; i ++)
cin >> a[i];
should be written like
for (int i = 0; i < 5; i ++)
cin >> a[i];
Also to avoid such an error you could use the range based for loop like
for ( auto &item : a ) std::cin >> item;

Logical error-encrypting a message in C++

the code should count each character. If the character is a number, it should count the previous character as much as the number.
So if the input is 'a', it should count 'a' once and assign it to acounter which now is equal to 1.
but if after 'a' is 3, it means 'aaa' and it should count 'a' three times and assign it to acounter which now is equal to 3.
Note: the program is for all of the alphabets but if this one isn't solved then what's the point of writing the rest?
I've tried put another loop exclusively for numbers but it didn't work.
char secret_message[1000];
int counter,number_counter;
int acounter=0;
gets(secret_message);
for (counter = 0 ; secret_message[counter] != NULL ; counter++)
{
if (secret_message[counter]=='a')
acounter++;
if (secret_message[counter] >= '0' && secret_message[counter] <= '9')
{
for(number_counter=1;number_counter<=secret_message[counter];number_counter++)
{
if (secret_message[counter-1]=='a')
acounter++;
}
}
}
cout<<endl<<"acounter is:"<<acounter;
if the input is a3 the output should be 3, but it's 52 !
You'll want to convert the digit from text to number, then use addition:
if (isdigit(secret_message[counter]))
{
const int value = secret_message[counter] - '0';
acounter += value;
}

How to replace certain items in a char array with an integer in C++?

Below is an example code that is not working the way I want.
#include <iostream>
using namespace std;
int main()
{
char testArray[] = "1 test";
int numReplace = 2;
testArray[0] = (int)numReplace;
cout<< testArray<<endl; //output is "? test" I wanted it 2, not a '?' there
//I was trying different things and hoping (int) helped
testArray[0] = '2';
cout<<testArray<<endl;//"2 test" which is what I want, but it was hardcoded in
//Is there a way to do it based on a variable?
return 0;
}
In a string with characters and integers, how do you go about replacing numbers? And when implementing this, is it different between doing it in C and C++?
If numReplace will be in range [0,9] you can do :-
testArray[0] = numReplace + '0';
If numReplace is outside [0,9] you need to
a) convert numReplace into string equivalent
b) code a function to replace a part of string by another evaluated in (a)
Ref: Best way to replace a part of string by another in c and other relevant post on SO
Also, since this is C++ code, you might consider using std::string, here replacement, number to string conversion, etc are much simpler.
You should look over the ASCII table over here: http://www.asciitable.com/
It's very comfortable - always look on the Decimal column for the ASCII value you're using.
In the line: TestArray[0] = (int)numreplace; You've actually put in the first spot the character with the decimal ASCII value of 2. numReplace + '0' could do the trick :)
About the C/C++ question, it is the same in both and about the characters and integers...
You should look for your number start and ending.
You should make a loop that'll look like this:
int temp = 0, numberLen, i, j, isOk = 1, isOk2 = 1, from, to, num;
char str[] = "asd 12983 asd";//will be added 1 to.
char *nstr;
for(i = 0 ; i < strlen(str) && isOk ; i++)
{
if(str[i] >= '0' && str[i] <= '9')
{
from = i;
for(j = i ; j < strlen(str) && isOk2)
{
if(str[j] < '0' || str[j] > '9')//not a number;
{
to=j-1;
isOk2 = 0;
}
}
isOk = 0; //for the loop to stop.
}
}
numberLen = to-from+1;
nstr = malloc(sizeof(char)*numberLen);//creating a string with the length of the number.
for(i = from ; i <= to ; i++)
{
nstr[i-from] = str[i];
}
/*nstr now contains the number*/
num = atoi(numstr);
num++; //adding - we wanted to have the number+1 in string.
itoa(num, nstr, 10);//putting num into nstr
for(i = from ; i <= to ; i++)
{
str[i] = nstr[i-from];
}
/*Now the string will contain "asd 12984 asd"*/
By the way, the most efficient way would probably be just looking for the last digit and add 1 to it's value (ASCII again) as the numbers in ASCII are following each other - '0'=48, '1'=49 and so on. But I just showed you how to treat them as numbers and work with them as integers and so. Hope it helped :)