Anagram detection method c++. Problems converting string to ascii value - c++

For anyone that might be able to help me figure this out. I am creating a method that will compare two strings and detect whether they are an anagram or not. An anagram is two strings that have the same letters, though they may be in a different order. For example "listen" and "iltsen" are anagrams.
I have decided to break the strings up into char arrays. I know that is working correctly because I tested it using cout on each array element. Next is where it goes wrong. I attempt to use the ASCII value of each char and add it to a variable for each array. This would mean that if the values match then they must be an anagram.
However for whatever unknown reason it is not working correctly. I am finding that it is reading index 0 twice for one array and not for the other. I am so confused beyond reason. I have absolutely no idea what this is occurring. I have tried multiple different solutions and had no luck finding out the problem. If anyone has any idea whats going on here I would greatly appreciate the help.
-Thanks!
#include "stdafx.h"
#include <iostream>
#include <string>
#include <math.h>
#include <iomanip>
#include <cctype>
#include <vector>
using namespace std;
bool isAnagram(string s1,string s2)
{
static char firstString[] = { 'c' };
static char secondString[] = { 'c' };
int size = s1.length();
static int count1 = 0;
static int count2 = 0;
cout << s1 << endl;
cout << s2 << endl;
if (s1.length() == s2.length())
{
for (int i = 0; i < size; i++)
{
firstString[i] = s1.at(i);
cout << i;
}
for (int i = 0; i < size; i++)
{
secondString[i] = s2.at(i);
cout << i;
}
cout << endl;
for (int i = 0; i < size; i++)
{
count1 = count1 + (int)firstString[i];
cout << "first" << i << ": " << firstString[i] << " = " << (int)firstString[i] << endl;
count2 = count2 + (int)secondString[i];
cout << "second" << i << ": " << secondString[i] << " = " << (int)secondString[i] << endl;
}
cout << count1 << " and " << count2 << endl;
if (count1 == count2)
return true;
}
else
return false;
count1 = 0;
count2 = 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
static char end;
do
{
string s1;
string s2;
cout << "Please enter the first string: ";
cin >> s1;
cout << endl << "Please enter the second string: ";
cin >> s2;
bool result = isAnagram(s1, s2);
static string resultString;
if (result == true)
resultString = "True";
else
resultString = "False";
cout << endl << "Anagram test result: " << resultString << endl;
cout << endl << "enter E for end or any other key to run again: ";
cin >> end;
cout << "----------------------------------------" << endl;
} while (end != 'e' && end != 'E');
return 0;
}

It's not useful to use static variables in your case, without them you wouldn't need the last 2 lines of isAnagram.
It's also useless to store both strings in char arrays because you can use them directly in your 3rd loop(also you are overflowing your buffer which has a size of 1)
for (int i = 0; i < size; i++)
{
std::cout << count1 << " ";
count1 = count1 + (int)s1.at(i);
cout << "first" << i << ": " << s1.at(i) << " = " << (int)s1.at(i) << endl;
count2 = count2 + (int)s2.at(i);
cout << "second" << i << ": " << s2.at(i) << " = " << (int)s2.at(i) << endl;
}
Also you can't say that 2 strings do contain the same letters by comparing the sum of their ASCII values, thats like saying 3 + 4 is the same as 2 + 5 because both give 7.
You could create an array of 52 ints, each element is a counter for its own letter, then you could loop over both strings with one loop where each letter of the first string is incrementing its element in the array and the second strings letters are decrementing elements.
if (s1.length() != s2.length())
return false;
std::vector<int> counts(52);
for (unsigned int i = 0; i < s1.length(); ++i)
{
++counts[s1[i] - (s1[i] < 91 ? 65 : 71)];
--counts[s2[i] - (s2[i] < 91 ? 65 : 71)];
}
be sure that the array is initialized to 0.
At the end you need to loop over the array, if one of the elements is not 0 it's not an anagram, else return true.
for (unsigned int i = 0; i < 52; ++i)
if (counts[i] != 0)
return false;
return true;

Related

ask the user if a sequence of two letters is in a random array of letters

The user inputs some desired length of a string of characters . then the program outputs a list of randomly generated characters. After which the user is prompted to input 2 characters (that either exist or does not exist whiten the list). the program will then output where the first character appears in the pair or say that the pair does not exist in the list.
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
int size, c;
char ltr1, ltr2;
cout << "How many letters do you want in your random sting? ";
cin >> size;
string str;
for (int i = 0; i < size; i++)
{
c = rand() % 26 + 'a';
str.push_back(c);
}
for (int i = 0; i < size; i++)
{
cout << str[i];
}
cout << endl << endl;
cout << "what pair of letters would you like to find?";
cin >> ltr1;
cin >> ltr2;
cout << endl;
for (int i = 0; i < size; i++)
{
if (char((str[i] == ltr1) && (str[i + 1] == ltr2)))
{
cout << "the pair is in the string starting at character number "
<< i << " in the string" << endl;
}
if (char((str[i] == ltr1) && (str[i + 1] != ltr2)))
{
cout << "the pair " << ltr1 << ltr2 << " is not in the string." << endl;
}
}
return 0;
}
the output is capable of determining weather or not the pair exist or not and will output the location however if you input a value greater than 25 it will run the final output multiple times.

How to output string second word first letter?

I need solution for this code, its almost done, but i dont understand how i can get first letter from second word, not first? In this code i get 1st letter of first word and dont know how to fix, to get first letter from second word of string which is input from user.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s, krt;
int sk;
cout << "Enter Array: ";
getline(cin, s);
sk = s.length();
cout << "Character in string: " << sk << endl;
int i, vst = 0, bas = 0;
for (i = 0; i < sk; i++) {
krt = s.substr(i, 1);
if (krt == " ")
vst = vst + 1;
}
cout << "Spaces count in string: " << vst << endl;
char tpb;
tpb = s[0];
int pbk;
pbk = tpb;
cout << "String second word first letter: " << tpb << " and its ASCII code: " << pbk << endl;
return 0;
}
Hope you understand what i need to get.
The main problem is that you use 0 as the index, instead of storing the index you want; the first non-space character that follows a space. At least, that is the definition I am going to assume - you didn't specify what to do for multiple consequetive spaces, nor strings containing non-alphabetic characters, such as "function()", where vim would say that '(' is the first character of the second word. Extending the code below to do that is left as an excercise to the reader.
There are a lot of other issues in your code; declarations that can be joined with the definition, doing a string comparison where you only need to compare a single character, and using for loops where there are algorithms to choose instead. Together these add a lot of noise to the code.
Finally, you need some code to handle the case of not having a second word, in order to not get undefined behaviour as in #Diodacus's code.
With regular for-loops:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
cout << "Enter Array: ";
getline(cin, s);
const int sk = s.length();
cout << "Character in string: " << sk << endl;
int vst = 0;
bool space_has_passed = false;
int first_nonspace_after_space_index = -1;
for (int i = 0; i < sk; i++) {
if (s[i] == ' ') {
vst = vst + 1;
space_has_passed = true;
} else if (space_has_passed && first_nonspace_after_space_index == -1) {
first_nonspace_after_space_index = i;
}
}
cout << "Spaces count in string: " << vst << endl;
if ( first_nonspace_after_space_index != -1 && sk > first_nonspace_after_space_index) {
const char tpb = s[first_nonspace_after_space_index];
const int pbk = tpb;
cout << "String second word first letter: " << tpb << " and its ASCII code: " << pbk << endl;
} else {
cout << "Need at least two words" << endl;
}
return 0;
}
You can cut it down by 7 lines if you use <algorithms>:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string s;
cout << "Enter Array: ";
getline(cin, s);
const int sk = s.length();
cout << "Character in string: " << sk << endl;
auto first_space = std::find(s.begin(), s.end(), ' ');
auto first_nonspace_afterspace = std::find_if(++first_space, s.end(), [](const char & c){ return c != ' '; });
int count_spaces = std::count(s.begin(), s.end(), ' ');
cout << "Spaces count in string: " << count_spaces << endl;
if( first_nonspace_afterspace != s.end() ) {
const char tpb = *first_nonspace_afterspace;
const int pbk = tpb;
cout << "String second word first letter: " << tpb << " and its ASCII code: " << pbk << endl;
} else {
cout << "Need at least two words" << endl;
}
return 0;
}
I suggest you to take a brief look at the string class documentation page (http://www.cplusplus.com/reference/string/string/), there is a lot of function that can help you manipulate string.
Based on the functions available in this class (eg. cbegin(), cend(), find(), c_str(), etc.), you could do something like this:
#include <iostream>
#include <string>
#include <ctype.h>
using namespace std;
int main()
{
string s;
cout << "Enter array: ";
getline(cin, s);
int sk = s.length();
cout << "Character in string: " << sk << endl;
int vst = 0;
for (auto i=s.cbegin(); i!=s.cend(); ++i)
if(isspace(*i)) vst++;
cout << "Spaces count in string: " << vst << endl;
string t = s.substr(s.find(" ") + 1, 1);
char tpb = *t.c_str();
int pkt = tpb;
cout << "String second word first letter: " << tpb << " and its ASCII code: " << pkt << endl;
return 0;
}
The main problem is that you print the first letter of the string passed in parameter:
tpb = s[0];
You should either:
memorize the index of the location of the first char of the second word
or
get the second word of the string passed in parameter and print the first char of this string
Finally, what is happening when there is only one word passed ?
You should also think about that. In the code above, if you pass the word test the program prints anyway String second word first letter: t and its ASCII code: 116 which is not true.
Try this:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string s, krt;
int sk;
cout << "Enter Array: ";
getline (cin, s);
sk = s.length();
cout << "Character in string: " << sk << endl;
int i, vst = 0, bas = 0;
for (i = 0; i < sk; i++)
{
krt = s.substr(i, 1);
if (krt == " ") vst = vst + 1;
}
cout << "Spaces count in string: " << vst << endl;
char tpb;
for (i = 0; i < sk; ++i) // Searching for first space
{
if (s[i] == ' ')
break;
}
tpb = s[i + 1];
int pbk;
pbk = tpb;
cout << "String second word first letter: " << tpb << " and its ASCII code: " << pbk << endl;
return 0;
}
This should do the trick.

Organize character types of array into separate arrays in C++

I am trying to write a small program that takes a user-defined string of a limited selection of characters (lowercase letters, parentheses, and the + and * operators), looks at each of the characters, and organizes them into separate arrays. I thought my approach to this exercise would be fairly straightforward, but I have run into some issues that I cannot figure out.
My problem becomes evident when I attempt to print the individual arrays to the screen. If all of the characters are of the same type (for example, "abcd"), the arrays print as intended. But if there is a combination of character types (for example, "(a+b)"), the arrays print incorrectly. I'm ashamed to say I have been banging my head against this (probably obvious) problem for many hours now and cannot seem to figure out what I have done wrong. Any input would be appreciated - I'm not looking for help writing the program, I just want to know what I have done wrong. I have included my code below:
#include <iostream>
#include <string>
using namespace std;
void charOrganizer(int[], char[], char[], char[], int, int&, int&, int&);
int main()
{
//Variable declaration
string userExpression;
int expressionArray[userExpression.length()];
char letterToken[userExpression.length()];
char parenthesesToken[userExpression.length()];
char plusTimesToken[userExpression.length()];
int letterTokenPos = 0;
int parenthesesTokenPos = 0;
int plusTimesTokenPos = 0;
//Prompt user for string input
cout << "Please enter a mathematical expression only using lowercase letters of the \nalphabet, parentheses, and/or the addition/multiplication operators."<< endl;
cin >> userExpression;
int arraySize = userExpression.length();
for (int i = 0; i < arraySize; ++i)
{
expressionArray[i] = userExpression[i];
}
charOrganizer(expressionArray, letterToken, parenthesesToken, plusTimesToken, arraySize, letterTokenPos, parenthesesTokenPos, plusTimesTokenPos);
//Print tokens to screen
cout << "LowerCase Letter Token values in your string:" << endl;
for (int i = 0; i < letterTokenPos; i++)
{
cout << letterToken[i] << endl;
}
cout << "Parentheses Token values in your string:" << endl;
for (int i = 0; i < parenthesesTokenPos; i++)
{
cout << parenthesesToken[i] << endl;
}
cout << "Operator Token values in your string:" << endl;
for (int i = 0; i < plusTimesTokenPos; i++)
{
cout << plusTimesToken[i] << endl;
}
return 0;
}
void charOrganizer (int charValue[], char letArr[], char parArr[], char pluTimArr[], int size, int& letPosition, int&parPosition, int& operPosition)
{
for (int i = 0; i < size; i++)
{
if (charValue[i] > 96 && charValue[i] < 123)
{
letArr[letPosition] = charValue[i];
cout << "Letter Copy Test: " << letArr[letPosition] << endl;
letPosition++;
}
else if (charValue[i] == 40 || charValue[i] == 41)
{
parArr[parPosition] = charValue[i];
cout << "Parentheses Copy Test: " << parArr[parPosition] << endl;
parPosition++;
}
else if (charValue[i] == 42 || charValue[i] == 43)
{
pluTimArr[operPosition] = charValue[i];
cout << "Operator Copy Test: " << pluTimArr[operPosition] << endl;
operPosition++;
}
else
{
cout << "Invalid input" << endl;
}
}
/*cout << "Print Array Test: " << endl;
for (int i = 0; i < letPosition; i++)
{
cout << letArr[i] << endl;
//cout << parArr[i] << endl;
//cout << pluTimArr[i] << endl;
}*/
}
see your below code. You are using the length of a empty string to declare arrays size like below. In this case all the array size will zero size only. Correct it properly:-
//Variable declaration
string userExpression;
int expressionArray[userExpression.length()];// it would be just like int expressionArray[0];
char letterToken[userExpression.length()];
char parenthesesToken[userExpression.length()];
char plusTimesToken[userExpression.length()];
int expressionArray[30];
char letterToken[30];
char parenthesesToken[30];
char plusTimesToken[30];
Else you declare these variables after you enter your string.

Mastermind string cout issue

Ok I have been struggling with this code and I think I have it written out right but here is the rules from my teacher
1 = implies right Number, Right Place.
2 = implies right Number, Wrong Place.
0 = implies Wrong Number.
So the computer decides on 12345; the user guesses 11235; the computer should respond with 10221. Hint: Watch out for a double number like 11 when there is only one.
I have it where it does all of that except I can not get it to show a 0 when it is wrong can you please help me every single part is written except that part here is my code
// Programming 2
// Mastermind
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
struct fields{//the list of variables used in my program
int size = 5;;
int range = 9;
char lowest = '0';
string guess;
string answer;
int number;
int correct;
int position;
bool gameover = false;
};
void gameplay(fields & info);//declaring the function
int main()
{
fields game;
gameplay(game);//calling the function
system("pause");
return 0;
}
void gameplay(fields & info){//calling the structure into the function
srand(time(0));//to randomize number
info.answer = "";//getting the number
for (int i = 0; i < info.size; i++)
{
char ch = info.lowest + rand() % info.range;
info.answer += ch;
}
info.number = 1;
info.correct = 0;
info.position = 0;
while (!info.gameover)//using a while loop to let them go until they guess it
{
cout << "Guess #" << info.number << ": Enter 5 numbers that are '0' through '9': ";//asking them to guess
cout << info.answer;
cout << "\n";
cin >> info.guess;
if (info.guess == info.answer)//if the guess is right this will end the game
{
cout << "Right! It took you " << info.number << " move";
if (info.number != 1) cout << "s";
cout << "." << endl;
info.gameover = true;
}
int correctNumbers = 0;
for (char const &ch : info.guess) //seeing if there are numebrs in the guess that is in the answer
{
if (info.answer.find(ch) != string::npos)
{
++correctNumbers;
}
}
int const digits = 5;
int correctPositions = 0;
int correctPosition[digits];
int test = 0;
for (int i = 0; i < digits; ++i)//telling which numbers is correct and displaying the 2 or 0 for number is correct or number is wrong
{
if (info.answer[i] == info.guess[i])
{
++correctPositions;
}
if (info.answer[i] == info.guess[i]){
correctPosition[i] = 2;
cout << correctPosition[i];
}
if (correctPosition[i] != 2){
correctPosition[i] = 1;
cout << correctPosition[i];
}
if (correctPosition[i] != 2 && correctPosition[i] != 1)){
correctPosition[i] = 0;
cout << correctPosition[i];
}
}
cout << "\nYou have " << correctPositions << " numbers in the correct position " <<endl;
cout << "You have " << correctNumbers <<" correct numbers in the wrong position"<< endl;
}
cout << "GAME OVER\n\n";
}

read text file then add character to list?

So I'm trying to complete this part of a program where I have to read a text file from Stdin and add it to the 'word list' wl. I get how to read from a text file but I don't know how to go about adding 'words' to a list, if that makes sense. So here's what I got:
string getWord(){
string word;
while (cin >> word){
getline(cin, word);
}
return word;
}
void fillWordList(string source[], int &sourceLength){
ifstream in.file;
sourceLength = 50;
source[sourceLength]; ///this is the part I'm having trouble on
Source is an array that determines how many words are read from the text and length is the amount printed on screen.
Any ideas on what I should begin with?
EDIT: Here's the program I'm writing the implementation for:
#include <iostream>
#include <string>
#include <vector>
#include "ngrams.h"
void help(char * cmd) {
cout << "Usage: " << cmd << " [OPTIONS] < INPUTFILE" << endl;
cout << "Options:" << endl;
cout << " --seed RANDOMSEED" << endl;
cout << " --ngram NGRAMCOUNT" << endl;
cout << " --out OUTPUTWORDCOUNT" << endl;
}
string source[250000];
vector<string> ngram;
int main(int argc, char* argv[]) {
int n, outputN, sl;
n = 3;
outputN = 100;
for (int i = 0; i < argc; i++) {
if (string(argv[i]) == "--seed") {
srand(atoi(argv[i+1]));
} else if (string(argv[i]) == "--ngram") {
n = 1 + atoi(argv[i+1]);
} else if (string(argv[i]) == "--out") {
outputN = atoi(argv[i+1]);
} else if (string(argv[i]) == "--help") {
help(argv[0]);
return 0; }
}
fillWordList(source,sl);
cout << sl << " words found." << endl;
cout << "First word: " << source[0] << endl;
cout << "Last word: " << source[sl-1] << endl;
for (int i = 0; i < n; i++) {
ngram.push_back(source[i]);
}
cout << "Initial ngram: ";
put(ngram);
cout << endl;
for (int i = 0; i < outputN; i++) {
if (i % 10 == 0) {
cout << endl;
}
//put(ngram);
//cout << endl;
cout << ngram[0] << " ";
findAndShift(ngram, source, sl);
} }
I'm supposed to use this as a reference but it dosen't help me too much.
Declaring raw array requires the size of the array to be a compile-time constant. Use std::vector or at least std::array instead. And pass source by reference if you want to fill it.