C++ - Adding Spaces to String - c++

Hey so I am trying to write a simple program that adds spaces to a given string that has none in C++ here is the code I have written:
#include <iostream>
#include <string>
using namespace std;
string AddSpaceToString (string input)
{
const int arrLength = 5;
int lastFind = 0;
string output;
string dictionary[arrLength] = {"hello", "hey", "whats", "up", "man"};
for (int i = 0; i < input.length(); i++)
{
for (int j = 0; j < arrLength; j++)
{
if(dictionary[j] == input.substr(lastFind, i))
{
lastFind = i;
output += dictionary[j] + " ";
}
}
}
return output;
}
int main ()
{
cout << AddSpaceToString("heywhatshelloman") << endl;
return 0;
}
For some reason the output only gives hey whats and then stops. What is going on I can't seem to make this very simple code work.

After reading "hey" and "whats", the value of i is more than the length of "hello" and hence no such substring exists for the code input.substr(lastFind, i).
You should check for the length of possible substring (dictionary[j]) and not i.
input.substr( lastFind, dictionary[j].size() )
Also you will have to change:
lastFind += dictionary[j].size();
So the if loop becomes:
if(dictionary[j] == input.substr(lastFind, dictionary[j].size() ))
{
lastFind += dictionary[j].size();
output += dictionary[j] + " ";
}

this works
#include <iostream>
#include <string>
using namespace std;
string AddSpaceToString (string input)
{
const int arrLength = 5;
unsigned int lastFind = 0;
string output;
string dictionary[arrLength] = {"hello", "hey", "whats", "up", "man"};
for (int j = 0; lastFind < input.size() && j < arrLength; ++j)
{
if(dictionary[j] == input.substr(lastFind, dictionary[j].size()))
{
lastFind += dictionary[j].size();
output += dictionary[j] + " ";
j = -1;
}
}
return output;
}
int main ()
{
cout << AddSpaceToString("heywhatshelloman") << endl;
return 0;
}

Related

Why garbage value showing up?

User enters a string like '3+2+1' or '1+3+2+1+3+1'. And I just have to sort the string. But after 4-5 test cases error shows up.
Input - 2
Output - �
Input - 2+1+2+2+2+3+1+3+1+2
Output - �+1+1+1+2+2+2+2+2+3
#include<iostream>
using namespace std;
int main()
{
string s;
cin>>s;
for(int i=0;i<s.size();i+=2)
{
for(int j=0;j<(s.size()-i);j+=2)
{
if(s[j]>s[j+2])
{
swap(s[j],s[j+2]);
}
}
}
cout<<s;
return 0;
}
As ggorlen said, garbage is showing up because you're accessing a value that's out of bounds. Try checking if your "j" index plus 2 is out of bounds before doing any swap.
#include<iostream>
using namespace std;
int main()
{
string s;
cin>>s;
for(int i=0;i<s.size();i+=2)
{
for(int j=0;j<(s.size()-i);j+=2)
{
if(j+2 < s.size() && s[j]>s[j+2])
{
swap(s[j],s[j+2]);
}
}
}
cout<<s;
return 0;
}
Input 2+1+2+2+2+3+1+3+1+2
Output 1+1+1+2+2+2+2+2+3+3
Value of j is going out of bounds. Try using insertion sort:
#include <bits/stdc++.h>
using namespace std;
void insertionSort(string s)
{
int key, j;
for (int i = 1; i < s.size(); i++)
{
key = s[i];
j = i - 1;
while (j >= 0 && s[j] > key)
{
s[j + 1] = s[j];
j = j - 1;
}
s[j + 1] = key;
}
for (int i = 0; i < s.size(); i++)
cout << s[i] << " ";
cout << endl;
}
int main()
{
string s;
cin>>s;
insertionSort(s);
return 0;
}
Hope you understand the code.

C++ - Decrypting a string from file

As you can see from the title I need to decrypt the strings in a text file. I have major problems with this so if you can help me I would really appreciate it.
First of all, here is the input file:
saoreecessinntfi
pmrrj ie2
borj
I want to decrypt these words like this:
sesnaestocifreni
primjer 2
broj
I have used the matrix 4x4 to do this, and here is the code so far:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream test;
test.open("test.txt");
char word[5][5];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
test >> word[i][j];
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
cout << word[j][i];
}
}
return 0;
}
Here is the output:
sesnaestocifreni
It only outputs the first word in text file. I think the problem with this is that I do not know how "long" is "i" and "j" in those other words beacuse the first word has 16 charachters so the counter "i" and "j" are set on 4. How to count each words charachters and if they are the same then decrpyt the word. Also if the word is right spelled I need to cout in the program "ERROR". For example
apple
I do not need to decrypt this word, beacuse it is right word, and "i" and "j" would not be the same or I do not know what I am talking about.
I think this should work just the fine for your case:
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
int matrixSize(std::string &str) {
auto x = sqrt(str.length());
return x - floor(x) == 0 ? x : 0;
}
int main() {
std::fstream file("test.txt");
std::string str;
while (std::getline(file, str)) {
if (int n = matrixSize(str)) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
std::cout << str.at(j * n + i);
std::cout << std::endl;
} else
std::cout << "ERROR" << std::endl;
}
return 0;
}
Sample test.txt file:
saoreecessinntfi
pmrrj ie2
borj
apple
Output on test run:
sesnaestocifreni
primjer 2
broj
ERROR
If I understand your problem correctly, you are given a line of n*n characters and need to unscramble it as given.
while (true) {
std::string line;
std::getline(cin, line);
if (line.empty())
break;
int n = 1;
while (n*n < line.size()) {
n++;
}
if (n*n != line.size()) {
std::cout << "ERROR" << std::endl;
continue;
}
std::string unscrambled;
for (int col = 0; col < n; col++)
for (int row = 0; row < n; row++)
unscrambled.append(1, line[row * n + col]);
std::cout << unscrambled << std::endl;
}

Run length encoding in C++

#include <iostream>
#include <string>
#include <vector>
using namespace std;
string compression(const string & str){
int i = str.size();
string letters;
letters[0] = str[0];
for (int j = 0; j < i; ++j){
int count = 1;
while (str[j] == str[j+1]){
count++;
j++;
}
letters.push_back('0' + count);
letters.push_back(str[j]);
}
return letters;
}
int main(){
string input;
char c;
try {
cout << "Enter the data to be compressesed: "<< endl;
cin >> input;
for (int z = 0; z < input.length(); ++z){
c = input.at(z);
}
if (!(c >= 'a' && c <= 'z')){
throw runtime_error("error: invalid input");
}
}
catch (runtime_error& excpt){
cout << excpt.what() <<endl;
return 0;
}
cout << "The compressed data is " << compression(input) << endl;
return 0;
}
The expected output is , repeated for each run of characters. Here is the amount of times is repeated in sequence.
Some examples:
aaeeeeae = 2a4e1a1e
rr44errre = invalid input
eeeeeeeeeeeeeeeeeeeee = 21e
the code works properly only if the character is repeated consecutively 9 times or less. for values of 10 and more the input is other symbols.
For example it stays blank for 10, so if input is 'aaaaaaaaaabb',output just would be 'a2b' instead of '10a2b'. For 11 its outputs ';',
so if input is 'aaaaaaaaaaabb', output is ';a2b' for some reason.
So my question is, how do i make the pushback work for all numbers and not just from 0-9?
Thank you for your time if u've gotten to here. ^^
If you can use c++11 or newer your function compression could look like:
string compression(const string & str){
int i = str.size();
string letters;
for (int j = 0; j < i; ++j){
int count = 1;
while (str[j] == str[j+1]){
count++;
j++;
}
letters += std::to_string(count);
letters.push_back(str[j]);
}
return letters;
}

Max Sum Of Integers

EDIT: solved! I was treating negative numbers test case as 0, instead of having the output be negative as well. thanks for the help!
Here is the challenge description: https://www.codeeval.com/open_challenges/17/
I keep getting a partially solved score. I want to know why. As in my eyes, this code works. And I believe that it is O(N) time. Thanks for looking!
Here is my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
int value = 0; //for holding the value of stock change
while (std::getline(file, line))
{
int pos = 0;
if(line.length() == 0)
continue;
else
{
std::istringstream iss(line);
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while (iss >> value)
{
list.push_back(value);
}
Values.push_back(list);
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
/*
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
*/
return 0;
}
so I swapped out some code now. I get better score but I it's still a partial.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int max(int a, int b)
{
if (a > b)
return a;
else return b;
}
int maxSubArray(vector<int> values)
{
int max_so_far = values[0];
int curr_max = values[0];
if (curr_max < 0)
{
curr_max = 0;
max_so_far = 0;
}
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0);
max_so_far = max(max_so_far, curr_max);
}
return max_so_far;
}
int main(int argc, char *argv[])
{
std::vector<vector<int> > Values; //to hold the values of the stock price change
ifstream file(argv[1]);
std::string line; //for the txt file input
std::string token; //for the subtring that will be converted from char to int
int value = 0; //for holding the value of stock change
int count = 0;// for holding how many total cases
while (!file.eof())
{
int pos = 0;
getline(file, line);
if(line.length() == 0)
continue;
else
{
std::vector<int> list; // temporary list of values to be pushed back into the 2-d vector
while ((pos = line.find(",")) != std::string::npos )
{
token = line.substr(0,pos);
value = atoi(token.c_str());
line.erase(0, pos + 1);
list.push_back(value);
}
value = atoi(line.c_str());
list.push_back(value);
Values.push_back(list);
++count;
}
}
for(int i = 0; i < Values.size(); ++i)
{
cout << maxSubArray(Values[i]);
cout << endl;
}
cout << " Printing the values : " << endl;
for (int j = 0; j < Values.size(); ++j)
{
for (int k = 0; k < Values[j].size(); ++k)
cout << Values[j][k] << " ";
cout << endl;
}
return 0;
}
Why are you passing the vector by value here?
int maxSubArray(vector<int> values)
That looks like a significant optimization opportunity.
I think you don't read the problem exactly right. When they say 'all contiguous sub ararys', they mean you have to take the max over all i andj of for(idx = i; i < j; ++i) { total += vec[idx]; }. Right now your code basically assumes i = 0 which isn't what you are supposed to do.
Just from looking at the output examples they provide, I can see that your code isn't going to give the answer that they expect.
it seems right, the only thing I can think of is that when the list gets long, your result can overflow, so change int to long long.
Besides technical optimizations suggested in other answers, concerning the algorithm, i think a little fix can make your algorithm work. When curr_max drops to a negative value, due to encountering a negative integer that exceeds curr_max, you can simply drop all the previous integers including the current value and start over. This fix is simple, you can add one line to your loop like this:
for(int i = 1; i < values.size(); ++i)
{
curr_max = max(values[i], curr_max + values[i]);
curr_max = max(curr_max, 0); // <---------------- add this line
max_so_far = max(max_so_far, curr_max);
}

C++ :String reversal not working?

I am having trouble understanding the output I am getting for this piece of code
#include<iostream>
#include<stdio.h>
using namespace std;
int main() {
int i = 0;
int j = 0;
int k = 0;
char ch[2][14];
char re[2][14];
cout << "\nEnter 1st string \n";
cin.getline(ch[0], 14);
cout << "\nEnter the 2nd string\n";
cin.getline(ch[1], 14);
for(i = 0; i < 2; i++) {
int len = strlen(ch[i]);
for(j = 0, k = len - 1; j < len; j++, k--) {
re[i][j]=ch[i][k];
}
}
cout << "\nReversed strings are \n";
cout << re[0];
cout << endl << re[1] << endl;
return 0;
}
for example
/*
Input :
hello
world
Output :
olleh<some garbage value>dlrow
dlrow
*/
Sorry if it very basic, but I can't understand the reason. Thanks in advance.
Make sure that re[0] and re[1] are null-terminated
For example during initialization you could do
for (int i = 0; i < 14; i++)
{
re[0][i] = '\0';
re[1][i] = '\0';
}
But aside from that I suggest to used std::string and std::reverse and the like.
for (i = 0; i < 2; i++)
{
int len = strlen(ch[i]);
for (j = 0, k = len - 1; j < len; j++, k--)
{
re[i][j] = ch[i][k];
}
re[i][len] = '\0';
}
you have to terminate your reversed strings.
also you should #include <string.h> for the strlen() function.
You forgot about the terminating zero for strings in array re Simply define the array the following way
char ch[2][14] , re[2][14] = {};
^^^^
Also take into account that you should remove header <stdio.h> because it is not used and instead of it include header <cstring>.
This task can be done with using standard algorithm std::reverse_copy
For example
#include <iostream>
#include <algorithm>
#include <cstring>
int main()
{
const size_t N = 2;
const size_t M = 14;
char ch[N][M] = {};
char re[N][M] = {};
std::cout << "\nEnter 1st string: ";
std::cin.getline( ch[0], M );
std::cout << "\nEnter the 2nd string: ";
std::cin.getline( ch[1], M );
std::cout << std::endl;
for ( size_t i = 0; i < N; i++ )
{
std::reverse_copy( ch[i], ch[i] + std::strlen( ch[i] ) , re[i] );
}
for ( const auto &s : re ) std::cout << s << std::endl;
return 0;
}