sum of digits at odd and even places of a string - c++

The output for the variable sum_e is negative which isn't what I expect it to be.
I have simply added the values at even and odd places and stored them in two variables. I checked for solutions and found ones with digit extraction from a number. None of them had a string input.
#include<iostream>
using namespace std;
int main(){
string s;
cin>>s;
int sum_e=0,sum_o=0;
int l=s.length();
for(int i=0;i<=l;i=i+2){
sum_o+=(s[i]-'0');
}
for(int j=1;j<=l;j=j+2){
sum_e+=(s[j]-'0');
}
cout<<sum_o<<endl<<sum_e;
return 0;
}
I subtracted '0' from the string index to convert it into int. One of the variables shows the right output and the other shows a negative one.

Your for loops run one time longer than the length of the array, so when i = l, s[i] will get an undefined/garbage value from memory. Use i < l and j < l rather than i <= l and j <= l, since the index in C++ begins at zero.
#include <iostream>
using namespace std;
int main(){
string s;
cin >> s;
int sum_e = 0, sum_o = 0;
int l = s.length();
for(int i = 0; i < l; i = i + 2){
sum_o += (s[i] - '0');
}
for(int j = 1; j < l; j = j + 2){
sum_e += (s[j] - '0');
}
cout << sum_o << endl << sum_e;
return 0;
}
To improve your code, use one for loop instead of two.
for(int i = 0; i < l; i++){
// Check if even (i%2 returns the remainder of i/2, so here i%2==1 means even)
if(i%2 == 1){
sum_e += (s[i] - '0');
}else{
sum_o += (s[i] - '0');
}
}

Array indexing in C++ starts from 0. You store the length of string as l, so elements of your string lies from s[0] to s[l-1]. At s[l] some garbage value is present which gets added to one of your variables, hence producing undesired results.
#include<iostream>
using namespace std;
int main(){
string s;
cin>>s;
int sum_e=0,sum_o=0;
int l=s.length();
for(int i=0;i<l;i=i+2){ // use <
sum_o+=(s[i]-'0');
}
for(int j=1;j<l;j=j+2){ // use <
sum_e+=(s[j]-'0');
}
cout<<sum_o<<endl<<sum_e;
return 0;
}
You can also do your odd and even position sum using a single loop. Your code size will reduce and look better
for(int i=0;i<l;i=i+2){
if(i%2==0)// even index means odd position numbers
sum_o+=(s[i]-'0');
else
sum_e+=(s[j]-'0');
}

Related

find element in array of strings

hey guys I am trying to solve a problem that requires making a program that searches for number k in n strings in an array and all its previous numbers including zero and finally calculates how many strings in array have these numbers . for example if the input is 2 strings ("0123","012") and search for number 1 the output should be 2 in this case .
so I made an array of strings and 2 loops to search in every char in every string (every element in array) but my program gives me wrong answer I don't know why , am I using a wrong function to search (find function) or what ?
#include <bits/stdc++.h>
using namespace std;
main() {
int n, k, sum = 0, good = 0;
cin >> n >> k;
string x[n];
for (int i = 0; i < n; i++) cin >> x[i];
for (int i = 0; i < n; i++) // string loop
{
for (int m = 0; m <= k; m++) // char loop
{
char c = '0' + m;
size_t search = x[i].find(c);
if (search != string::npos) {
sum++;
}
}
if (sum == (k + 1)) good++;
}
cout << good;
}

How to compare a certain character with another character of a string

In the following code, I am having trouble comparing specific letters two given strings.
#include <bits/stdc++.h>
using namespace std;
int main() {
int m, n;
cin >> m >> n;
cin.ignore();
string phrases[m];
string records[n];
for (int i = 0; i < m; i++) {
getline(cin, phrases[i]);
}
for (int i = 0; i < n; i++) {
getline(cin, records[i]);
}
int lowBound;
sort(phrases, phrases + m);
int ans = 0;
bool stillIs;
for (int i = 0; i < n; i++) {
lowBound = lower_bound(phrases, phrases + m, records[i]) - phrases;
if (lowBound == m) {
continue;
}
stillIs = true;
for (int j = 0; j < records[i].length(); i++) {
if (records[i][j] == phrases[lowBound][j]) {
stillIs = false;
}
}
if (stillIs) {
ans++;
}
}
cout << ans;
return 0;
}
On line 33, if (records[i][j] == phrases[lowBound][j]), it is not giving me an error, but if I run it with this line, nothing happens, but when I comment the if statement out, it works properly, but obviously not giving me the correct answer. Is there any way I can compare these two strings (the second one is larger in size than the first one) to find whether the first one is the start of the second one?
Thanks!
You are incrementing i instead of j in the loop at line 32
You have your test backwards in line 33 - you want to set stillIs = false if the characters don't match, (i.e., !=)
I haven't fully read your code, but those two problems jumped out at me, so see if that sorts it out

2d vector c++ use in Longest Common Substring

I am working on codechef practice problem in which I have to find longest common substring. ( Its practice problem so don't down vote )
Following wiki and some resources online I got the algorithm
https://en.wikipedia.org/wiki/Longest_common_substring_problem
After understanding I wrote the algorithm in c++ , but its compiling but not running successfully . Throwing error while assigning value to vector matrix .
An invalid parameter was passed to a function that considers invalid parameters fatal.
1) Whats wrong with my LCSubstring function
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int max(int a, int b) {
return a > b ? a : b;
}
int LCSubString(string str1 , string str2) {
// create 2d matrix
vector<vector<int>> matrix;
int maxlength = 0;
for (int i = 0; i <= str1.length(); i++) {
for (int j = 0; j <= str2.length(); j++) {
if (i == 0 && j == 0) {
matrix[i][j] = 0;
continue;
}
if (str1[i - 1] == str2[j - 1]) {
matrix[i][j] = matrix[i - 1][j - 1] + 1;
maxlength = max(maxlength, matrix[i][j]);
}
else {
matrix[i][j] = 0;
}
}
}
return maxlength;
}
int main()
{
int t;
int count = 0;
string str;
int len;
cin >> t;
while (t--) {
cin>> str;
len = LCSubString(str, "chef");
if (len >= 2) {
count++;
}
}
cout << count << endl;
return 0;
}
You did not properly initialize std::vector<std::vector<int>> matrix. They do not automatically resize when you access them with [], you need to set the proper size beforehand, like this:
vector<vector<int>> matrix(str.length()+1);
for (int i = 0; i <= str1.length(); ++i)
matrix[i] = vector<int>(str2.length()+1, 0);
Additionally, you are not properly checking for i == 0 or j == 0. If only one of them is zero then the first if in your loop won't hit and you subsequently try to read string[-1]. I don't know whether it would be correct for your algorithm, but try using logical or (||) instead of and (&&).

Sum of two arrays, carry over operation C++

Beginner here, and I'm stuck. The main program is provided to us, and we're supposed to write 3 functions. readBig(), addBig(), and printBig(). I'm stuck on the addBig() function. It's supposed to sum two arrays, and perform the carry operation. I cannot figure out where I'm going wrong. The carry operation is working out for me.
Any help/direction is appreciated.
#include <iostream>
using namespace std;
//This program will test three functions capable of reading, adding,
//and printing 100-digit numbers.
// Do not change these function prototypes:
void readBig(int[]);
void printBig(int[]);
void addBig(int[], int[], int[]);
// This constant should be 100 when the program is finished.
const int MAX_DIGITS = 100;
//There should be no changes made to the main program when you turn it
in.
int main(){
// Declare the three numbers, the first, second and the sum:
int num1[MAX_DIGITS], num2[MAX_DIGITS], sum[MAX_DIGITS];
bool done = false;
char response;
while (not done)
{
cout << "Please enter a number up to "<<MAX_DIGITS<< " digits: ";
readBig(num1);
cout << "Please enter a number up to "<<MAX_DIGITS<< " digits: ";
readBig(num2);
addBig(num1, num2, sum);
printBig(num1);
cout << "\n+\n";
printBig(num2);
cout << "\n=\n";
printBig(sum);
cout << "\n";
cout <<"test again?";
cin>>response;
cin.ignore(900,'\n');
done = toupper(response)!='Y';
}
return 0;
}
//ReadBig will read a number as a string,
//It then converts each element of the string to an integer and stores
it in an integer array.
//Finally, it reverses the elements of the array so that the ones digit
is in element zero,
//the tens digit is in element 1, the hundreds digit is in element 2,
etc.
void readBig(int num[])
{
for(int i = 0; i < MAX_DIGITS; i++){
num[i] = 0;
}
string numStr;
getline(cin,numStr);
string temp;
//store into array
for (int i = 0; i < numStr.length(); i++){
temp = numStr.at(i);
num[i] = stoi(temp);
}
int arrayLength = MAX_DIGITS;
int temp2;
for (int i = 0; i < (arrayLength/2); i++){
temp2 = num[i];
num[i] = num[(arrayLength - 1) - i];
num[(arrayLength - 1) - i] = temp2;
}
}
//AddBig adds the corresponding digits of the first two arrays and
stores the answer in the third.
//In a second loop, it performs the carry operation.
void addBig(int num1[], int num2[], int sum[])
{
for (int i = 0; i < MAX_DIGITS; i++){
sum[i] = num1[i] + num2[i];
if (sum[i] > 9){
sum[i] = sum[i] - 10;
sum[i+1] = sum[i+1] + 10;
}
}
}
//PrintBig uses a while loop to skip leading zeros and then uses a for
loop to print the number.
void printBig(int array[])
{
int i = 0;
while (array[i] == 0){
i++;
}
for (int j = i; j < MAX_DIGITS;j++){
cout << array[j] << endl;
}
}
Looks like readBig function isn't correct, it stores least significiant digit into num[numStr.length()-1], after reversing it became num[MAX_DIGITS -1 - ( numStr.length()-1], but addNum assumes last digit is num[0].
Correct variant:
void readBig(int num[])
{
//clear num, read numStr...
//store into array
int count = 0;
for (int i = numStr.length()-1; i >= 0; --i){
temp = numStr.at(i);
num[count++] = stoi(temp);
}
|
So this
sum[i] = sum[i] - 10;
sum[i+1] = sum[i+1] + 10;
should most likely be this
sum[i] = sum[i] - 10;
sum[i+1] = sum[i+1] + 1;
Since its the next decimal place it shouldnt be incremented by 10
Also when you get to the last cell in your array
sum[i+1] = sum[i+1] + 1;
this will be out of bounds, so depending on the requirments you will want to change this

Classis task for splitting weights into 2 trucks (C++) (Dynamic Programming)

I have a task that by given line of weights of cages and I have to split them into 2 trucks. The split should be done like this that |a - b| to have least value where 'a' is the common weight of the cages in the first truck and 'b' is the common weight of the cages of second truck. My program seems to work but when I upload it to hackerrank abort function is called. So where is my fault? Here is the code:
#include <iostream>
#include <vector>
#include <sstream>
#include <cstring>
using namespace std;
int main()
{
string input;
int k;
while (getline(cin, input))
{
/* splitting the input into integers */
vector<int> v;
istringstream iss(input);
while (iss >> k) v.push_back(k);
/* --- II --- */
unsigned long sum = 0;
unsigned i, j;
for (i = 0; i < v.size(); i++)
sum += v[i];
vector<char> can;
can.push_back(1);
for (i = 1; i <= sum; i++)
can[i] = 0;
for (i = 0; i < v.size(); i++)
{
for (j = sum; j+1 > 0; j--)
{
if (can[j])
{
can[j + v[i]] = 1;
}
}
}
for (i = sum / 2; i > 1; i--)
{
if (can[i])
{
if (i <= sum - i)
{
cout << i << " " << sum - i << endl;
break;
}
else
{
cout << "a should be <= b";
break;
}
}
}
}
return 0;
}
How can this work?
You create an empty vector of char, push one single value into it and that try to assign value passed the first:
...
vector<char> can;
can.push_back(1); // can contains one single value
for (i = 1; i <= sum; i++)
can[i] = 0; // Error "vector subscript out of range" in debug mode
If you do not ask the control of vector subscript you will just invoke undefined behaviour.
But if you just want to expand the vector, you can repeatedly can push_back:
for (i = 1; i <= sum; i++)
can.push_back(0);