I explain you the working of this program.
step 1: enter the no. of time you want to run the loop.
step 2: enter two strings s1 and s2.
output : it will give you a string s3 that does not contain any character from string s2.
problem: I am unable to understand the working of for loop, and why the value of hash is 257, and how is loops working.
The code is given below.
#include <iostream>
using namespace std;
#include<string.h>
int main()
{
int t;
cout<<"enter any no. to run the loop"<<endl;
cin>>t;
while(t--)
{
string s1,s2,s3;
int i,j,l1,l2;
cout<<"enter two strings s1 and s2"<<endl;
cin>>s1>>s2;
l1=s1.length( );
l2=s2.length( );
int hash[257];
for(i=0;i<257;i++)
{
hash[i]=0;
}
for(i=0;i<l2;i++)
{
hash[s2[i]]++;
}
for(i=0;i<l1;i++)
{
if(hash[s1[i]]==0)
s3=s3+s1[i];
}
cout<<s3<<endl;
}
return 0;
}
This program figures out which characters in the first string are not contained in the second string.
Example input for the program:
1
abcdefghijklmnopqrstuvwxyz
helloworld
Example output (thanks to #mch for correction)
abcfgijkmnpqstuvxyz
Edit: Note that this is of course case sensitive as characters a and A produce different integer values.
Here is some commentary on the program:
#include <iostream>
using namespace std;
#include <string.h>
int main() {
// Do the whole program as many times as the user says
int t;
cout << "enter any no. to run the loop" << endl;
cin >> t;
while (t--) {
string s1, s2, s3;
int i, j, l1, l2;
// read strings and get their respective lengths
cout << "enter two strings s1 and s2" << endl;
cin >> s1 >> s2;
l1 = s1.length();
l2 = s2.length();
// Array with 257 elements
int hash[257];
// Initialize all elements of array with 0
for (i = 0; i < 257; i++) {
hash[i] = 0;
}
// Count occurrences of characters in second string
// s2[i] is the character at position i in s2
// Increase the value of hash for this character by 1
for (i = 0; i < l2; i++) {
hash[s2[i]]++;
}
// Iterate over s1 characters
// If hash[i] == 0: character i is not contained in s2
// s3 => string of letters in s1 that are not contained in s2
for (i = 0; i < l1; i++) {
if (hash[s1[i]] == 0)
s3 = s3 + s1[i];
}
// output s3
cout << s3 << endl;
}
return 0;
}
The code computes an histogram of occurrences of the letters in s1 and copies the letters of s2 that have zero occurrence.
It can crash for any char type not restricted to the range [0,256] (!)
There's a comment above explaining the for-loops.
int hash[257] could actually be int hash[256] . There are 256 different values that can fit in a char (8 bits).
Related
I have an array and I want to subtract each of the elements consecutively, ex: {1,2,3,4,5}, and it will result to -13 which is by 1-2-3-4-5.
But I don't declare or make those numbers fixed as they're taken from the input (user). I only make it like, int array[100] to declare the size.
Then, to get the inputs, I use the for loop and insert them to the array. Let's say first input is 10, then array[0] must be 10 and so on.
The problem is, how do I subtract them? I have two options:
The first element of the array (array[0]) will subtract the next element (array[1]) right after the user input the second element, and the result (let's say it's int x) will subtract the next element (array[2]) after the user input it and so on.
I'll have the user input all the numbers first, then subtract them one by one automatically using a loop (or any idea?) *These elements thing refer to the numbers the user input.
Question: How do you solve this problem?
(This program will let the user input for as much as they want until they type count. Frankly speaking, yeah I know it's quite absurd to see one typing words in the middle of inputting numbers, but in this case, just how can you do it?)
Thanks.
Let's see my code below of how I insert the user input into the array.
string input[100];
int arrayInput[100];
int x = 0;
for (int i = 0; i >= 0; i++) //which this will run until the user input 'count'
{
cout << "Number " << i+1 << ": ";
cin >> input[i];
arrayInput[i] = atoi(input[i].c_str());
...
//code to subtract them, and final answer will be in int x
...
if (input[i] == "count")
{
cout << "Result: " << x << endl;
}
}
You can/should use a dynamic sized container like std::vector as shown below:
#include <iostream>
#include <vector>
int main()
{
int n = 0;
//ask user how many input he/she wants to give
std::cout << "How many elements do you want to enter: ";
std::cin >> n;
std::vector<int> vec(n); //create a vector of size n
int resultOfSubtraction = 0;
//take input from user
for(int i = 0 ; i < n ; ++i)
{
std::cin >> vec.at(i);
if(i != 0)
{
resultOfSubtraction-= vec.at(i);
}
else
{
resultOfSubtraction = vec.at(i);
}
}
std::cout<<"result is: "<<resultOfSubtraction<<std::endl;
return 0;
}
Execute the program here.
If you want a string to end the loop then you can use:
#include <iostream>
#include <vector>
#include <sstream>
int main()
{
std::vector<int> vec;
int resultOfSubtraction = 0, i = 0;
std::string endLoopString = "count";
std::string inputString;
int number = 0;
//take input from user
while((std::getline(std::cin, inputString)) && (inputString!=endLoopString))
{
std::istringstream ss(inputString);
if(ss >> number)
{
vec.push_back(number);
if(i == 0)
{
resultOfSubtraction = number;
}
else
{
resultOfSubtraction-= number;
}
++i;
}
}
std::cout<<"result is: "<<resultOfSubtraction<<std::endl;
return 0;
}
Why is there an extra character at the end of my string?
#include <iostream>
using namespace std;
int main() {
int num;
cin >> num; // Reading input from STDIN
cout << "Input number is " << num << endl; // Writing output to STDOUT
char c1, s2[10];
for (int i=0; i<num; i++)
{
cin >> c1;
if(c1==0){
break;
}
s2[i] = c1;
}
cout <<"output= "<< s2;
}
output example
4
Input number is 4
a l e x
output= alex#
Why is the "#" being added to the end of the string? At first i thought it was a random garbage value but every time I run the program its always the same symbol
cout, when printing a c-string, expects it to zero terminated. Whereas you haven't done so for the array s2.
You can zero initialize the entire array:
char s2[10] = {};
Or just zero terminate the last byte:
int i = 0;
for (i=0; i<num; i++)
{
cin >> c1;
if(c1==0) {
break;
}
s2[i] = c1;
}
s2[i] = '\0';
In any case, you need to be wary of potential buffer overflow (e.g. if num is too large).
Alternatively, you can consider using std::string instead of a fixed length array.
You're reading from a memory location that hasn't been initialized. By using an array of ten characters and only initializing the first four (or whatever else the number is), all other characters stay uninitalized. What data is actually read from an uninitialized location is undefined, meaning it's pretty much up to your compiler that chooses to read the equivalent value of "#" from that location. You can fix that issue by using a memory bit of the appropriate size. For this, you just replace the line
char c1, s2[10];
with
char c1;
char* c2 = new char[num + 1] //num + 1 is necessary to contain a string terminator, see the other answers
this way, you dynamically allocate exactly the size you need.
Don't forget to delete[] c2; afterwards.
You are using a Character sequence well explained here.
By convention, the end of strings represented in character sequences
is signaled by a special character: the null character, whose literal
value can be written as '\0' (backslash, zero).
In this case, the array of 20 elements of type char called foo can be
represented storing the character sequences "Hello" and "Merry Christmas" as:
Notice how after the content of the string itself, a null character
('\0') has been added in order to indicate the end of the sequence.
The panels in gray color represent char elements with undetermined
values.
I offer a c++17 solution with the constructor initialization although I may prefer either a dynamic array or std::string instead of a char.
I also added a simple integer check that always should be used.
Also a few versions of avoiding the use of the whole namespace std for various reasons, mostly to avoid unnecessary errors.
#include <iostream>
#include <limits> //numeric_limits
using std::cout, std::endl, std::cin; //<- explicit declared
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
};
cout << "Input number is " << num << endl;
char c1, s2[num+1]{}; // Initialize with an empty string
for (int i = 0; i < num; i++)
{
cin >> c1;
if (c1 == 0) {
break;
}
s2[i] = c1;
}
cout << "output= " << s2 << endl;
return 0;
}
This happens because s2 is actually not a string and does not have the \0 character, which would mean the end of the string. Therefore, cout prints your string and will continue to move further in memory, byte by byte, interpreting each of them as a character to be output until it encounters the \0 character. In order to fix this, you can initialize s2 with an empty string, so the array will initially be completely filled \0.
#include <iostream>
using namespace std;
int main() {
int num;
cin >> num;
cout << "Input number is " << num << endl;
char c1, s2[10] = ""; // Initialize with an empty string
for (int i = 0; i < num; i++)
{
cin >> c1;
if (c1 == 0) {
break;
}
s2[i] = c1;
}
cout << "output= " << s2;
}
I am able to count the number of characters in my string using length() function.
But i want to calculate the number of different characters in my string.
i.e. say string is "Hello world"
So here number of different strings are H,e,l,o, ,w,r,d.
so 8 different characters.
The best way to do is a method called frequency checking. Basically create a vector of size 128. Go through the string and for every character, increment the frequency that matches its ASCII value. Finally, iterate over the freq vector and count how many non zero entries you have. Code should look like this:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
string s = "Hello World";
vector<int>freq(128);
for(int i = 0; i < s.length(); i++)
freq[s[i]]++;
int counter = 0;
for(int i = 0; i < 128; i++)
if(freq[i] > 0)
counter++;
cout << counter << "\n";
}
Vector of size 128 works fine because ASCII codes only go from 0 to 127.
Another way is to initialize a std::set and insert every character of the string into that one at a time. Finally, output the size of the set. This works because set doesn't allow duplicate entries. The code for this looks like:
#include<iostream>
#include<set>
#include<string>
using namespace std;
int main()
{
string s = "Hello World";
set<char>x;
for(int i = 0; i < s.length(); i++)
x.insert(s[i]);
cout << x.size() << "\n";
}
To count the number of unique characters, you can use sd::sort followed by std::unique. It will reshuffle the contents and return an iterator to the last unique character in your string. Subtract begin() and you have the result.
I think that an unordered_map is the best way to achieve that.
Here is the code if you want the total number of char in a string, grouped by unique chars.
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
string s="test string";
unordered_map<char,int> map;
for (const char &c: s) { //for each char in string
map[c]++;
}
for (auto &e: map) //for each unique char in map
cout<<"char: "<<e.first<<" number: "<<e.second<<endl;
return 0;
}
Output
char: n number: 1
char: e number: 1
char: i number: 1
char: t number: 3
char: s number: 2
char: number: 1
char: g number: 1
char: r number: 1
But if you want only the total number of unique chars
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
string s="test string";
unordered_map<char,int> map;
for (const char &c: s) {
map[c]++;
}
int count =0;
for (auto &e: map)
count++;
cout<<"Unique chars: "<<count<<endl;
}
Output
Unique chars: 8
Well you can write your own functions to deal with that like this
#include <iostream>
using namespace std;
string uniqueChars(string str) {
string newStr = "";
bool arr[128];
for(int i = 0;i < 128; i++) {
arr[i] = false;
}
char c;
for(int i = 0, n = str.length();i < n; i++) {
c = str[i];
if(c < 0 || c > 127) {
continue;
}
if(!arr[c]) {
arr[c] = true;
newStr += c;
}
}
return newStr;
}
int main(void) {
string a = "Hello It's a wonderful world";
string b = uniqueChars(a);
cout << a << " => " << a.length() << "\n" <<
b << " => " << b.length();
return 0;
}
Output:
Hello It's a wonderful world => 28
Helo It'sawndrfu => 16
I am to write a program that will take 2 strings, put them into a function called "build_histogram" and build a int array that keeps count of how many times each letter appears in each string, then compare the arrays and if they are equal, then they are anagrams. The instructions state we are to ignore all symbols(ex. !, whitespaces, _, etc.) and it is not to be case sensitive.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void build_histogram(int letters[], string s) {
for(int i = 0; i < s.length(); i++) {
letters[s[i]]++;
}
}
int main()
{
string s1, s2;
int* histogram1[26];
int* histogram2[26];
cout << "Enter two strings." << endl;
getline(cin, s1);
getline(cin, s2);
build_histogram(histogram1[26], s1);
build_histogram(histogram2[26], s2);
if(histogram1 != histogram2) {
cout << "They are not anagrams." << endl;
}
else {
cout << "They are anagrams!" << endl;
}
return 0;
}
This is what I have so far, but no matter what strings I enter, I cannot get the program to print anything besides "Enter two strings."
EDIT
So this is my code now...it counts the number of characters correctly in each string, the only issue now is the "if else" statement at the bottom still doesn't recognize that the arrays are the same, also it's having a hard time when symbols like '!' are in the strings.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void build_histogram(int letters[], string s) {
for(int i = 0; i < s.length(); i++) {
char currLetter = s[i];
currLetter = tolower(currLetter);
int index = currLetter - 97;
letters[index]++;
}
}
int main()
{
string s1, s2;
int histogram1[26] = {0};
int histogram2[26] = {0};
cout << "Enter two strings." << endl;
getline(cin, s1);
getline(cin, s2);
build_histogram(histogram1, s1);
build_histogram(histogram2, s2);
if (histogram1 == histogram2) {
cout << "They are not anagrams." << endl;
} else {
cout << "They are anagrams!" << endl;
}
return 0;
}
Two strings are anagrams if they have the same length and one std::is_permutation() of the other.
See http://en.cppreference.com/w/cpp/algorithm/is_permutation
One could write a function to check if two strings are anagrams like this:
bool is_anagram(const std::string& s1, const std::string& s2) {
return s1.size() == s2.size() &&
std::is_permutation(std::begin(s1), std::end(s1),
std::begin(s2), std::end(s2));
}
This isnt your whole solution but it is definitely a start.
Your letters[] array only has indexes 0 through 25, therefore you'd want to convert your letters to correspond with 0-25.
Here is an easy way to do so:
void build_histogram(int* letters[], string s) {
for(int i = 0; i < s.length(); i++) {
char currLetter = s[i];
///force letter to become lowercase
currLetter = tolower(currLetter);
///make letter an ASCII value
int index = currLetter - 97;//subtract 97 to get a range from 0 to 25
letters[index]++;
}
}
This implementation makes all letters into their lowercase forms.
Additionally, the number of instances of 'a' would be stored in index 0, and 'z' in index 25.
Hopefully this helps you go down the right track!
So I have a program here that is supposed to print to the screen permutations of a user input word that can be 4 to 10 characters long and there are supposed to be as many permutations as there are letters in the word. I almost have complete success, but there is one issue. When it prints the permutations, after the first about 2 permutations, it starts to not use all the letters and/or the same letter twice.
For example, if the user input word is "bill", the output is as follows:
llib illb ibll lbii
The fourth is is obviously not correct. The problem is more apparent with words that have more letters. I need it to only use the letters it has once. How do I go about fixing this in my code? Here is my code.
int main(void)
{
string word;
string randword;
string reverse;
int length;
int i = 0;
int j = 0;
string randCH;
cout << "Enter any word 4 to 10 letters in length: ";
cin >> word;
//Checks if word is less than 4 or greater than 10
while (1)
{
/*The code here is in the final program and I know it works. The problem is not here*/
}
length = word.length();
//Uses reverse function
reverse = reverseit(word);
/*reverseit is a function outside of main that makes the word backwards*/
//Prints all permutations
cout << endl << reverse << " ";
for (i = 0; i < word.length() - 1; i++)
{
for (j = 0; j < word.length(); j++)
{
randCH = word.substr(rand() % length, 1);
cout << randCH;
}
cout << " ";
cout << endl;
you can use std::next_permutation which is already built to achieve this:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string word;
cin >> word;
sort(word.begin(),word.end());
do {
cout << word <<endl;
} while(next_permutation(word.begin(),word.end()));
}