//EDIT
the code below works only in case that str1 has only 1 beginning letter of str2; how to fix it?
for ex. if str1 / 2 = overflow / flo it works.
but if str1 is overflowfabc (has two "f"s) --> it doesn't work
//
I need to check for a word in a string using simple loop. The idea is:
find an element in str1 that is equal to 1. element of str2
if it exists, we set flag = 1, and it remains 1 if following elements are also equal. If they are not, flag is set to 0.
.
#include <iostream>
using namespace std;
int main() {
string str1, str2;
int flag;
cout << "Enter a string 1: ";
getline(cin, str1);
cout << "Enter a string 2: ";
getline(cin, str2);
for(int i = 0; i < str1.size(); i++)
{
if (str1[i] == str2[0]) // find element in str1 that is equal to first element of str2
{
flag = 1; //
for(int j = i+1; j < i + str2.size(); j++)
if (str1[j] != str2[j-i]) // checking if following elements are also equal
{
flag = 0; // if any of them is not equal
break;
}
if (flag==1)
cout << "str2 is Substring of str1" ;
else
cout << "str2 is NOT Substring" ;
}
}
return 0;
}
bool isSubStr(const string& parent, const string& child)
{
// Check each starting position
for (int i=0; i<(parent.size()-child.size()+1); ++i)
{
// Check if the substring starts at this position
// TODO make this a helper method to avoid the need for a flag
bool isSubString = true;
for (int j=0; j<child.size(); ++j)
{
if (parent[i + j] != child[j])
{
isSubString = false;
break;
}
}
if (isSubString)
{
return true;
}
}
return false;
}
The string class in C++ contains a function named find, and in my opinion you should use that.
The documentation can be found here.
An excerpt about the Return value:
The position of the first character of the first match.If no matches
were found, the function returns string::npos.
#include <iostream>
using namespace std;
int main() {
string str1, str2;
cout << "Enter a string 1: ";
getline(cin, str1);
cout << "Enter a string 2: ";
getline(cin, str2);
size_t found = str1.find(str2);
if (found != string::npos)
cout << "str2 is Substring of str1" << endl;
else
cout << "str2 is NOT Substring" << endl;
return 0;
}
It is shorter and easier to understand. So why not going with that ?
Otherwise I believe your code is not correct in more than one aspect; e.g.
you print out the text depending on the flag variable within the for loop. This does not look right to me.
the second for loop looks strange to me. I believe you are trying to program something that you believe might be considered sophisticated and well thought. To be honest with you, I suggest that do not try to do that. Do simple and clear.
Following your comment I took the time to try to improve your code.
#include <iostream>
using namespace std;
int main() {
string str1, str2;
int flag = 0;
cout << "Enter a string 1: ";
getline(cin, str1);
cout << "Enter a string 2: ";
getline(cin, str2);
for(unsigned int i = 0; i < str1.size(); i++) {
if (str1[i] == str2[0]) { // find element in str1 that is equal to first element of str2
unsigned int j = 0;
for( ; j < str2.size(); j++) {
if ( str1[i+j] != str2[j] ) { // checking if following elements are also equal
break;
}
}
if ( j == str2.size() ) { // if j equals the size of substring then all chars seem equal
flag = 1;
break;
}
}
}
if ( flag )
cout << "str2 is Substring of str1" ;
else
cout << "str2 is NOT Substring" ;
return 0;
}
Related
Create a program titled str_compress.cpp. This program will take a sentence input and remove all spaces from the sentence. (A good first step in encryption programs) Make sure that both the input and output strings are all stored in a single variable each. Do not use numbers or symbols. Include both upper-case and lower-case letters. Account for cases with multiple spaces anywhere.
This is what I have so far:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0, j = 0, len;
string str;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
for (i = 0; i < len; i++)
{
if (str[i] == ' ')
{
for (j = i; j < len; j++)
{
str[j] = str[j + 1];
}
len--;
}
}
cout << str << endl;
system("pause");
return 0;
}
I can eliminate spaces, but only one at a time. If I copy and paste the for loop, I can remove all spaces for how many loops there are. I'm thinking that I can loop the for loop over and over until all spaces are gone, but I'm not sure how to do that. Also, I can't use anything like remove_all() or erase().
This is a strong clue for how the authors of your exercise want you to write your code:
Make sure that both the input and output strings are all stored in a single variable each
You should make a new string:
string new_str;
Use your loop over the input string. For each char in the string, check whether it is a space. If yes, do nothing. If no, append it to the output string:
for (i = ...)
{
char c = str[i];
if (c != ' ')
new_str.push_back(c);
}
Your loop's logic when removing a space is wrong. For instance, after removing a space, you then skip the next char in the string, which may be another space. Also, although you are decrementing the len, you don't resize the string to the new len before printing the new str value.
It should look more like this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
i = 0;
while (i < len)
{
if (str[i] == ' ')
{
for (j = i + 1; j < len; ++j)
{
str[j - 1] = str[j];
}
--len;
}
else
++i;
}
str.resize(len);
cout << str << endl;
/* or, if you are not allowed to use resize():
cout.write(str.c_str(), len);
cout << endl;
*/
/* or, if you are not allowed to use write():
if (len < str.length())
str[len] = '\0';
cout << str.c_str() << endl;
*/
system("pause");
return 0;
}
Live Demo
However, your instructions do say to "Make sure that both the input and output strings are all stored in a single variable each", which implies that separate std::string variables should be used for input and output, eg:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
str2 = str;
len = str2.length();
i = 0;
while (i < len)
{
if (str2[i] == ' ')
{
for (j = i + 1; j < len; ++j)
{
str2[j - 1] = str2[j];
}
--len;
}
else
++i;
}
str2.resize(len);
cout << str2 << endl;
/* or:
cout.write(str2.c_str(), len);
cout << endl;
*/
/* or:
if (len < str2.length())
str2[len] = '\0';
cout << str2.c_str() << endl;
*/
system("pause");
return 0;
}
Live Demo
Alternatively:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
str2.reserve(len);
for(i = 0; i < len; ++i)
{
char ch = str[i];
if (ch != ' ')
str2 += ch;
}
cout << str2 << endl;
system("pause");
return 0;
}
Live Demo
This is what worked for me. Thank you everyone for the help!!
int main()
{
int i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
for (i = 0; i < len; ++i)
{
char ch = str[i];
if (ch != ' ')
str2 += ch;
}
cout << str2 << endl;
system("pause");
return 0;
}
I'm a student currently studying C++ and I have a problem with a code that I am trying to create. The code I am supposed to create is meant to find the hamming distance of 2 words that the user will input. (For e.g "Ironman" and "Iron" hamming distance is "3")
However, I ran into an error when I tried compiling and I can't seem to find out what the problem is. The error of "String subscript out of range" keeps popping up if the first input is longer than the second input.(It only fails to work when I try to input "Spiderman Ironman". Shorter words such as "Sean Sea" works fine.) If the second input is longer than the first input, OR if both the inputs are the same length, the entire code works fine.
string str1;
string str2;
cout << "Question 1" << endl;
cout << "Input two words (separated by space or enter) : ";
cin >> str1;
cin >> str2;
int count = hamming_distance(str1, str2);
cout << "> Hamming distance between \"" << str1 << "\" and \"" << str2 << "\" is " << count << endl;
int i;
int firstLength = str1.length();
int secondLength = str1.length();
int thirdLength;
int counter = 0;
//if the longest word is first string (Where the issue is causing)
if (firstLength > secondLength)
{
thirdLength = firstLength - secondLength;
for (i = 0; i < firstLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
for (i = 0; i < thirdLength; i++)
{
counter++;
}
}
//if the longest word is second string
else if (secondLength > firstLength)
{
thirdLength = secondLength - firstLength;
for (i = 0; i < secondLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
for (i = 0; i < thirdLength; i++)
{
counter++;
}
}
//if both words have the same length
else if (firstLength == secondLength)
{
for (i = 0; i < firstLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
}
return counter;
It would be greatly appreciated if y'all could help me find out what the actual problem is with my code. Thank you!
You need to initialise your variables correctly:
int firstLength = str1.length();
int secondLength = str2.length();
You're also determining that one string is bigger than another, then proceeding to access elements in the shorter string according to the length of the longer one, which is giving you the subscript out of range error. You need to revise the tests when firstLength > secondLength and vice versa.
I have a string that contains X words (between each word there is a space) I have to move the words in a circular motion to the left according to the number that the user inserts. For example:
"hi my name is aviv and",
the user entered 2. "name is aviv and hi my" I'm looking for legality that repeats itself but I can not find.
Thanks for the guidance. Most importantly, I can not use built-in libraries
Update:
I see there are examples with libraries, I can not use any library.
So what I've done so far.
I wrote a function that gets a string and a number from the user, to move left.
Before sending the string to the function I try to calculate the number of characters I need to move.
My output is - "name is avivhi my"
Regarding the function:
When it gets a string without spaces it works great.
This is my code:
int main()
{
char str[] = "hi my name is aviv";
char str2[] = "hi my name is aviv";
int CountSpace = 0, CountWord = 0;
int Size = 18, flag = 0;
int MoveLeft, Index = 0;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
CountSpace++;
}
}
CountWord = CountSpace + 1;//Understand how many words there are in a string.
cin >> MoveLeft;
if (MoveLeft >= CountWord)//
{
MoveLeft = (MoveLeft - ((MoveLeft / CountWord) * CountWord));//the size of movment;//To reduce the amount of moves if there is such a possibility
}
for (int i = Size - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
flag++;
}
if (flag == MoveLeft)
{
Index = Size - 1 - (i + 1);//That's the amount of characters I have to move
break;
}
}
MoveLeft = Index;
//This code belongs to the function that accepts a string and the amount to move the characters
for (int i = 0; i < Size; i++)
{
if (i + MoveLeft < Size)
{
str[i] = str2[i + MoveLeft];
}
else
{
str[i] = str2[(i + MoveLeft) - Size];
}
}
cout << "Move Left: " << MoveLeft << endl << str << endl << str2 << endl;
return 0;
}
Here's a hint:
vector<string> words = Your_Code_To_Split_Input_Into_Words();
int count = words.size();
int shift = Your_Code_To_Read_Users_Input();
// print the sentence with the rotation specified by shift
for (int i = 0; i < count; i++)
{
int shifted_index = (i + shift) % count; // modulo math implements circular rotation
string spacing = (i == 0) ? "" : " "; // add a space before each word, except first word
cout << spacing << words[shifted_index];
}
cout << endl;
One possible answer, i highly recommend using vectors instead of regular arrays, it's easy and more dynamic, but i didn't use it because you said you can't use built-in libraries.
#include <iostream>
#include<string>
using namespace std;
int main() {
string a[10000];
int counter = 0;
string b = "hi my name is aviv and";
string temp = "";
int userNum = 2;
for(int i=0;i<b.length() ; i++){
if(b[i]!=' '){
temp+=b[i];
}
else if(b[i]==' ' && temp.length()){
a[counter]= temp;
temp = "";
counter++;
}
}
if(temp.length()){
a[counter] = temp;
}
for(int i=userNum;i<=counter+userNum;i++){
cout<<a[i%(counter+1)]<<endl;
}
}
If you can make use of std::rotate() from <algorithm>, this is much easy to do with that. Parse the words using std::stringstream and store to std::vector. Then apply the shif directly to the vector.
Sample Output: https://www.ideone.com/rSPhPR
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> vec;
std::string str = "hi my name is aviv and";
std::string word;
std::stringstream sstr(str);
while(std::getline(sstr, word,' '))
vec.emplace_back(word);
int shift;
std::cout << "Enter the Shift: ";
std::cin >> shift;
std::rotate(vec.begin(), vec.begin() + shift, vec.end());
for(const auto& it: vec)
std::cout << it << " ";
return 0;
}
Here's a snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define MaxWords 10
int main()
{
stringstream ss;
ss.str("hi my name is aviv and");
string str[MaxWords];
int i;
for (i =0; std::getline(ss, str[i],' ');i++ )
{
cout << str[i] << " ";
}
int n;
cout << "\nEnter pos to split : ";
cin >> n;
for (int j = n; j <= i; j++)
{
cout << str[j] << " ";
}
for (int j = 0; j < n; j++)
{
cout << str[j] << " ";
}
cout << endl;
return 0;
}
Output:
I wrote code to check the input, I set the HavePunct flag always false. However when I input hello,world!! it returns the wrong results to me. Please let me know if you see any problems with my code:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string s,result_s;
char ch;
bool HavePunct = false;
int sLen = s.size();
cout << "Enter a string:" << endl;
getline(cin, s);
//检测字符串是否有符号
for (string::size_type i = 0;i != sLen; ++i) {
ch = s[i];
if (ispunct(ch)) {
HavePunct = true;
}
else
result_s += ch;
}
if (HavePunct) {
cout << "Result:" << result_s;
}
else {
cerr << "No punction in enter string!" << endl;
system("pause");
return -1;
}
system("pause");
return 0;
}
You are computing the length of the line before you enter any input. Hence, sLen is always zero. Move that line so it is after the line where you read the input.
cout << "Enter a string:" << endl;
getline(cin, s);
int sLen = s.size();
I cannot be sure, however it would seem because your iterator's upper bound is determined by the variable sLen, which you assign to be s.size() before you receive a string, therefore effectively making your upper bound 0 and causing your for loop never to execute.
Try this and let me know:
getline(cin, s);
int sLen = s.size();
for (string::size_type i = 0;i != sLen; ++i) {
ch = s[i];
if (ispunct(ch)) {
HavePunct = true;
}
else
result_s += ch;
}
i am trying to print an array of unknown length backwards so wrote that the loop should start at the terminator and go to the first letter printing each letter but it keeps printing only the first
#include <iostream>
using namespace std;
int main()
{
char word[10];
int i;
cout << "Enter a word: " ;
cin >> word;
for ( word[i]= '\0'; word[1] <0; word[i] --)
{
cout << word[i] << endl;
}
return 0;
}
You can print you C-style string backwards whith this one-liner:
reverse_copy(word,word+strlen(word),ostream_iterator<char>(cout));
Also please consider using std::string:
string word;
cin >> word;
copy(word.rbegin(),word.rend(),ostream_iterator<char>(cout));
You will need to #include the following headers for the above examples to work:
<algorithm>, <iostream>, <iterator>, <string> and <cstring>
Replace your loop it does nothing:
for (i= strlen(word); i >=0; i--)
{
cout << word[i] << endl; //endl is optional
}
Also for in case of long strings you may have to increase size of char array or its better to use
string word;
for (i= word.size(); i >=0; i--)
{
cout << word[i] << endl; //endl is optional
}
Here is a simple way to print a C-style string backwards.
for (size_t i = 0, i_end = std::strlen(word); i != i_end; ++i)
{
std::cout << word[i_end - i - 1];
}
std::cout << "\n";
Note that I save the result of strlen so that it is not called every time.
To get the result you want, you might want to use this code...
char word[10];
int sz;
do {
cout << "Enter a word: ";
cin >> word;
sz = strlen(word);
} while (sz > 10);
for (int i = sz; i >= 0; i--)
{
cout << word[i];
}