I have two strings:
string word;
string alphabet;
word has some input that I passed on to; let's say "XYZ".
alphabet has the alphabet except XYZ, so it's "ABCDEFGHIJKLMNOPQRSTUVW"
When I tried to concat them with "+=", all I get is word (i.e. "XYZ"). I want to make it look like this:
XYZABCDEFGHIJKLMNOPQRSTUVW
What am I doing wrong? Code is basicly this vvvv
===========================encryption.cpp=================================================
#include <cstdlib>
#include <iostream>
#include "encryption.h"
#include <string>
encryption::encryption()
{
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
string encryption::removeletter(string word,char letter)
{
//remove letter
string temp;
int indis=0;
for(int i = 0; word[i] != '\0'; i++)
{
if(word[i] != letter)
{
temp[indis]=word[i] ;
indis++;
}
}
word=temp;
return word;
}
This is the function i have proplems with :
void encryption::encrypt(string word)//main.cpp is just calling this atm
{
string temp;
int pos;
//getting rid of the repeating letters
for(int i = 0; i < word.length(); i++)
{
if( (pos = temp.find(kelime[i])) < 0)
temp += word[i];
}
word=temp;//that ends here
//taking words letters out of the alphabet
for(int i = 0; i < word.length(); i++)
{
alfabet=removeletter(alfabe,word[i]);
}
for(int i = 0; i < word.length()-1; i++)
{
for(int j=0;alfabet[j] !='\0'; j++)
if(alfabet[j+1] =='\0') alfabet[j]='\0';
}
/* I tried += here */
}
===========================encryption.h====================================================
#ifndef encryption_h
#define encryption_h
#include<string>
class encryption
{
public:
encryption();
void encrypt(string word);
string removeletter(string word,char letter);
//some other functions,i deleted them atm
public:
string alphabet;
string encryptedalphabet;
//staff that not in use atm(deleted)
};
#endif
===========================main.cpp======================================================
#include <cstdlib>
#include <iostream>
#include "encryption.h"
#include <string>
string word;
encryption encrypted;
cin>>word;
encrypted.encrypt( word);
+= is how you do it, you must be doing something else.
string word = "XYZ";
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVW";
alphabet += word;
cout << alphabet << "\n";
output
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Use
word.append(alphabet);
Note that when you want to concatenate many strings, it's more efficient to use a stringstream to avoid unnecessary string copying.
string word = "XYZ";
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVW";
word += alphabet;
Now you can print 'word', and you will find your answer.
Related
I expected this to be straightforward using a for loop with replace(str.begin(), str.end(), "x", "y") but instead "x" and "y" are a certain character in an array, so: replace(str.begin(), str.end(), arrX[1], arrY[1]) in the loop:
for (int i = 0; i < arraySize; i++) {
replace( str.begin(), str.end(), arrX[i], arrY[i]);
}
but in my code:
#include <iostream>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
string Caesar(string str) {
char alph[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
string caesar = "abcdefghijklmnopqrstuvwxyz";
const int arraySize=sizeof(alph)/sizeof(alph[0]);
rotate(caesar.begin(), caesar.begin()+3, caesar.end());
for (int i = 0; i < arraySize; i++) {
replace(str.begin(), str.end(), alph[i], caesar[i]);
}
return str;
}
int main() {
cout << Caesar("hello");
}
caeser string is alph rotated by three.
Outputting caesar gives expected results. (abcdef... becomes xyzabc... when just printing caesar.)
My loop seems to be the thing messing it up, when given hello it produces ccaaa. I tested replacing one letter and it worked but it seems my for loop is what the problem is, but I can't seem to find out what is wrong.
UPDATE:
I found out a way to do it that supports non alphabetical characters using a while loop that checks if it is alphabetical and then goes through the alphabet comparing each letter to a letter in the string until they match and than replace that with the rotated Caesar alphabet, if they don't match it goes to the next one and when found it resets 'j' to 0 so it can do it again for the next letter by increment 'i' this time, if the char is not a letter it just increases 'i' to the next char to just skip over it until it reaches the new letter or the end of the string.
#include <iostream>
#include <algorithm>
using namespace std;
bool IsInArray(string array, char element) {
for(int i = 0; i < array.length(); i++){
if(array[i] == element){
break;
}
}
}
string rot(int n, string str) {
transform(str.begin(), str.end(), str.begin(), ::tolower);
string alph = "abcdefghijklmnopqrstuvwxyz";
string ciph = alph;
rotate(ciph.begin(), ciph.begin() + n, ciph.end());
int i = 0;
int j = 0;
while (i < str.length()) {
if (IsInArray(alph, str[i])) {
if (str[i] == alph[j]) {
str[i] = ciph[j];
i++;
j = 0;
}
else {
j++;
}
}
else {
i++;
}
}
return str;
}
int main() {
cout << rot(2, "This cipher works with more than just alpha chars!");
return 0;
}
Here's one way to do it using standard functions and a lambda function:
string Caesar(std::string str) {
std::string caesar = "abcdefghijklmnopqrstuvwxyz";
std::rotate(caesar.begin(), caesar.end()-3, caesar.end());
std::transform(str.begin(), str.end(), str.begin(),
[caesar](char c) -> char { return caesar[c - 'a']; });
return str;
}
Note: it uses the char code to get the index, so it would have to be changed to handle anything other than "abc...xyz".
As an optimization: if you're using just letters a-z lowercase, you can do it without using the two arrays and without using the function leftRotatebyOne. Instead use the ASCII values.
std::string Caesar(std::string str){
int delta = 'z' - 'a' + 1;
int rotateBy = 3;
for(int i = 0; i < str.length(); i++){
char c = str[i] - rotateBy;
if(c < 'a')
c += delta;
str[i] = c;
}
return str;
}
I have a string variable
string = " this is my string"
I want to store every word separated by a whitespace into an array
array[0]="this";
array[1]="is";
array[2]="my";
array[3]="string";
You could use std::copy with std::istringstream and std::istream_iterator and std::back_inserter:
vector<string> v;
istringstream ss(" this is my string");
copy(istream_iterator<string>(ss), istream_iterator<string>(), back_inserter(v));
LIVE
First you have to include "sstream" class like:
#include <sstream>
Then use below code:
string str= "this is my string"
int len = str.length();
string arr[len];
int i = 0;
stringstream ssin(str);
while (ssin.good() && i < len){
ssin >> arr[i];
++i;
}
for(i = 0; i < len; i++){
cout << arr[i] << endl;
}
For this case, you can use string delimiter concept
strtok(const char * str, int delimiter);
for your case, delimiter is "white space".
program:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This a sample string";
char * output_after_delimiter_applied;
char *out_arr[4];
int i=0;
printf("The original string is %s\n", str);
output_after_delimiter_applied = strtok (str," ");
while (output_after_delimiter_applied != NULL)
{
out_arr[i] = output_after_delimiter_applied;
output_after_delimiter_applied = strtok (NULL, " ");
// NULL parameter is for continuing the search
// delimiter is "white space".
i++;
}
for(i=0; i < 4 ; i++)
printf("%s\n", out_arr[i]);
return 0;
}
we can add any no. of delimiters with in double quotes. it is like string (delimiter) search.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin , s) ; #input of string from user
int counter = 0;
int max_word = -1;
int len = s.length(); #length of string
string max = " ";
string counter_word = " ";
for (int i = 0; i < len; i++)
{
if(s[i] != ' ')
{
counter++;
}
if(s[i] == ' ' || i == len - 1)
{
if(counter > max_word)
{
max_word = counter;
//handling end of string.
if(i == len - 1)
max = s.substr(i + 1 - max_word, max_word); #sub string command that prints the longest word
else
max = s.substr(i - max_word, max_word);
}
counter = 0;
}
}
cout << max_word << " " << max << endl; #output
return 0;
}
The current output is '4 This' on entering the string "This is cool".
How do I get it to print '4 This; Cool' ?
On running it in Linux through the terminal, it gives me the error
" terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr Aborted (core dumped) "
If I have understood you correctly then you mean the following
#include <iostream>
#include <sstream>
#include <string>
int main()
{
std::string s;
std::getline( std::cin, s );
std::string::size_type max_size;
std::string max_word;
std::string word;
std::istringstream is( s );
max_size = 0;
while ( is >> word )
{
if ( max_size < word.size() )
{
max_size = word.size();
max_word = word;
}
else if ( max_size == word.size() )
{
max_word += "; ";
max_word += word;
}
}
std::cout << max_size << ' ' << max_word << std::endl;
}
If to enter string
This is cool
then the output will be
4 This; cool
The basic idea here is to add each character to a temporary (initially empty) string until a space is encountered. At each instance of a space, the length of the temporary string is compared to the length of the "maxword" string, which is updated if it is found to be longer. The temporary string is emptied (reset to null using '\0') before proceeding to the next character in the input string.
#include <iostream>
#include <string>
using namespace std;
string LongestWord(string str) {
string tempstring;
string maxword;
int len = str.length();
for (int i = 0; i<=len; i++) {
if (tempstring.length()>maxword.length())
{
maxword=tempstring;
}
if (str[i]!=' ')
{
tempstring=tempstring+str[i];
}
else
{
tempstring='\0';
}
}
return maxword;
}
int main() {
cout << LongestWord(gets(stdin));
return 0;
}
#include <iostream>
using namespace std;
string longestWordInSentence(string str) {
// algorithm to count the number of words in the above string literal/ sentence
int words = 0;
for (int i = 0; i < str.length(); i++) {
if (str[i] == ' ') {
words++;
}
}
// incrementing the words variable by one as the above algorithm does not take into account the last word, so we are incrementing
// it here manually just for the sake of cracking this problem
words += 1; // words = 5
// words would be the size of the array during initialization since this array appends only the words of the above string
// and not the spaces. So the size of the array would be equal to the number of words in the above sentence
string strWords[words];
// this algorithm appends individual words in the array strWords
short counter = 0;
for (short i = 0; i < str.length(); i++) {
strWords[counter] += str[i];
// incrementing the counter variable as the iterating variable i loops over a space character just so it does not count
// the space as well and appends it in the array
if (str[i] == ' ') {
counter++;
}
}
// algorithm to find the longest word in the strWords array
int sizeArray = sizeof(strWords) / sizeof(strWords[0]); // length of the strWords array
int longest = strWords[0].length(); // intializing a variable and setting it to the length of the first word in the strWords array
string longestWord = ""; // this will store the longest word in the above string
for (int i = 0; i < sizeArray; i++) { // looping over the strWords array
if (strWords[i].length() > longest) {
longest = strWords[i].length();
longestWord = strWords[i]; // updating the value of the longestWord variable with every loop iteration if the length of the proceeding word is greater than the length of the preceeding word
}
}
return longestWord; // return the longest word
}
int main() {
string x = "I love solving algorithms";
cout << longestWordInSentence(x);
return 0;
}
I have explained every line of the code in great detail. Please refer to the comments in front of every line of code. Here is a generalized approach:
Count the number of words in the given sentence
Initialize a string array and set the size of the array equal to the number of words in the sentence
Append the words of the given sentence to the array
Loop through the array and apply the algorithm of finding the longest word in the string. It is similar to finding the longest integer in an array of integers.
Return the longest word.
My original solution contained a bug: If you were to input 2 words of length n and 1 word of length n + k, then it would output those three words.
You should make a separate if condition to check whether the word length is the same as before, if yes, then you can append "; " and the other word.
This is what I would do:
Change if(counter > max_word) to if(counter >= max_word) so words of the same length are also taken into account.
Make the max string by default (so "" instead of " "). (See next point)
Add an if condition in the if(counter >= max_word)second if condition to see if the max string is not empty, and if it's not empty append "; "
Changing max = to max += so that it appends the words (in the second condition)
Wouldn't it be easier for you to split the whole line into a vector of string ?
Then you could ask the length of each element of the string and then print them. Because right now you still have all the words in a single string making each individual word hard to analyse.
It would also be hard, as you requested, to print all the words with the same length if you use a single string.
EDIT :
Start by looping through your whole input
Keep the greater length of word between the current one and the previously saved
Make a substring for each word and push_back it into a vector
Print the length of the bigger word
Loop through the vector and print each word of that size.
Look the following website for all references about vectors. dont forget to #include
www.cplusplus.com/reference/vector/vector/
#include <iostream>
#include <vector>
#include <string>
void LongestWord(std::string &str){
std::string workingWord = "";
std::string maxWord = "";
for (int i = 0; i < str.size(); i++){
if(str[i] != ' ')
workingWord += str[i];
else
workingWord = "";
if (workingWord.size() > maxWord.size())
maxWord = workingWord;
}
std::cout << maxWord;
}
int main(){
std::string str;
std::cout << "Enter a string:";
getline(std::cin, str);
LongestWord(str);
std::cout << std::endl;
return 0;
}
Source: http://www.cplusplus.com/forum/beginner/31169/
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s,a;
char ch;
int len,mlen=0;
getline(cin,s);
char* token=strtok(&s[0]," ");
string r;
while(token!=NULL)
{
r=token;
len=r.size();
if(mlen<len)
{
mlen=len;
a=token;
}
token = strtok(NULL, " ");
}
cout<<a;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
string str;
getline(cin,str);
cin.ignore();
int len =str.length();`
int current_len=0,max_len=0;
int initial=0,start=0;
int i=0;
while(1)
{
if(i==len+2)
{break;}
if(str[i]==' '|| i==len+1)
{
if(current_len>max_len)
{
initial=start;
max_len=current_len;
}
current_len=0;
start=i+1;
}
else
{
current_len++;
}
i++;
}
for (int i = 0; i < max_len; i++)
{
cout<<str[i+initial];
}
cout<<endl<<max_len<<endl;
return 0 ;
}
I want to check how many times the letters of the alphabet are in a text file.
#include <iostream>
#include <string>
#include <fstream>
#include <cctype>
using namespace std;
int main()
{
char alphabet[]="abcdefghijklmnopqrstuvwxyz";
//char alphabet[26]= {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int letter_c[26]; //will contain the times each letter is repeated
string line;
//get text file
ifstream myfile ("hi.txt");
//if file opens...
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
//lowercase everything
for (int i = 0; i < line.length(); i++)
{
line[i] = tolower(line[i]);
}
//check if letter ? is in that text file and how many times
for (int i = 0; i < line.length(); i++)
{
int count=0;
for(int j=0; j<strlen(alphabet);i++)
{
if(line[i]==alphabet[j])
{
cout<<"letter: alphabet "<<alphabet[j]<<endl;
cout<<"letter: text "<<line[i]<<endl;
letter_c[i]=count++;
//cout<<count<<endl;
}
cout<<alphabet[i]<<" "<<letter_c[i]<<endl;
}
}
}
//close file
myfile.close();
}
//file not found
else cout << "Unable to open file";
return 0;
}
I believe this if statement is what is messing up my code:
if(line[i]==alphabet[j])
{
cout<<"letter: alphabet "<<alphabet[j]<<endl;
cout<<"letter: text "<<line[i]<<endl;
letter_c[i]=count++;
//cout<<count<<endl;
}
I have tried using line[i].compare(alphabet[j]) == 0
and I have also tried strcmp (line[i],alphabet[j]) == 0
and neither of them work.
You are over complicating the logic, instead just increase the count in letter_c at the found letter index, something like following :
int letter_c[26] = {0};
while ( myfile >> c )
{
if( isalpha(c) )
{
++letter_c[ tolower(c) - 'a' ] ; // Change to lower case, subtract ascii of a
}
}
You want std::map. Your key is the letter, and your value is the count.
Something like this should do what you want:
std::map<char, unsigned int> count;
std::fstream file("foo.txt");
char letter;
while(file >> letter)
{
count[c] += 1;
}
If you want to treat uppercase and lowercase letters as the same, then use std::tolower:
count[std::tolower(c)] += 1;
This also has the added benefit of counting punctuation and special characters.
So, I am trying to read a string from cin, then loop through the string to count which characters in that string are actually letters in the English alphabet. I have wrote a program that works just fine, but I want to know if there is a more efficient way of doing this, without looping through the entire English alphabet.
#include <iostream>
#include <string>
using namespace std;
int main() {
string my_str; //will use to store user input
getline(cin, my_str); //read in user input to my_str
int countOfLetters = 0; //begine count at 0
string alphabet = "abcdefghijklmnopqrstuwxyz"; //the entire english alphabet
for(int i = 0; i < my_str.length(); i++){
for(int j = 0; j < alphabet.length(); j++){
if (tolower(my_str.at(i)) == alphabet.at(j)){ //tolower() function used to convert all characters from user inputted string to lower case
countOfLetters += 1;
}
}
}
cout << countOfLetters;
return 0;
}
EDIT: Here is my new and improved code:
#include <iostream>
#include <string>
using namespace std;
int main() {
string my_str; //will use to store user input
getline(cin, my_str); //read in user input to my_str
int countOfLetters = 0; //begine count at 0
string alphabet = "abcdefghijklmnopqrstuwxyz"; //the entire english alphabet
for(unsigned int i = 0; i < my_str.length(); i++){
if (isalpha(my_str.at(i))){ //tolower() function used to convert all characters from user inputted string to lower case
countOfLetters += 1;
}
}
cout << countOfLetters;
return 0;
}
enter code here
Use isalpha() to see which characters are letters and exclude them.
So, you could modify your code like this:
#include <iostream>
#include <string>
using namespace std;
int main() {
string my_str;
getline(cin, my_str);
int countOfLetters = 0;
for (size_t i = 0; i < my_str.length(); i++) { // int i produced a warning
if (isalpha(my_str.at(i))) { // if current character is letter
++countOfLetters; // increase counter by one
}
}
cout << countOfLetters;
return 0;
}
You could perhaps use isalpha:
for(int i = 0; i < my_str.length(); i++)
if (isalpha(my_str.at(i))
countOfLetters++;
You can use the std::count_if() algorithm along with the iterator interface to count characters for which some predicate returns true. The predicate can use std::isalpha() to check for alphabetical characters. For example:
auto count = std::count_if(std::begin(str), std::end(str),
[&] (unsigned char c) { return std::isalpha(c); });
You could also check if the int cast is between 65-90 or 97-122
at example
(int)'a'
Should give 97
This will be the most performant method without any doubt.
Its better than using isalpha().
Check http://www.asciitable.com/ for ASCI Numbers
isalpha works well for this particular problem, but there's a more general solution if the list of characters to accept wasn't so simple. For example if you wanted to add some punctuation.
std::set<char> good_chars;
good_chars.insert('a'); good_chars.insert('A');
good_chars.insert('b'); good_chars.insert('B');
// ...
good_chars.insert('z'); good_chars.insert('Z');
good_chars.insert('_');
// the above could be simplified by looping through a string of course
for(int i = 0; i < my_str.length(); i++){
countOfLetters += good_chars.count(my_str[i]);
}