I'm new to C++ programming and this is the task that i've to do, but i can't get the desired output even after trying and trying. Can anyone please look into code and let me know what should do, i know my code is incomplete but i don't know how to proceed from here.
Task: Write a program, using functions only, with the following features.
Program reads paragraph(s) from console and stores in a string.
Program then counts the occurrences of double letter appearing in any word of the paragraph(s) and outputs the characters along with its number of occurrences.
If a double letter is appearing more than one time the program should show this only one time along with its total frequency in paragraph.
Output letters must be in sequence.
Sample input (file):
Double bubble deep in the sea of tooth with teeth and meet with riddle.
Sample output:
bb 1
dd 1
ee 3
oo 1
This is my code:
#include <iostream>
#include <conio.h>
#include <cstring>
#include <ctime>
using namespace std;
int counter = 0;
char alphabets[26] = { 0 };
void alternatives();
int main() {
alternatives();
_getch();
return 0;
}
void alternatives() {
char str[] = "Double bubble deep in the sea of tooth with teeth and meet with riddle.";
int count = 0;
for (int j = 0; j < strlen(str); j++)
str[j] = tolower(str[j]);
for (int i = 0; i < strlen(str); i++) {
if (str[i] == str[i + 1]) {
counter++;
cout << str[i] << str[i + 1] << "\t" << counter << endl;
}
counter = 0;
}
}
Output:
bb 1
ee 1
oo 1
ee 1
ee 1
dd 1
You have 26 letters (I assume) so you need 26 counts. A simple array would do
int counters[26] = { 0 }; // initialise all counts to zero
Now when you find a repeated letter you need to increment the appropriate count, something like
for (int i = 0; i < strlen(str); i++)
{
char letter = str[i];
if (letter >= 'a' && letter <= 'z' && // is it a letter and
letter == str[i + 1]) // is it repeated?
{
counters[letter - 'a']++; // increment count
}
}
Note the use of letter - 'a' to get the offset into the array of counts
Finally you need to output the results
for (char letter = 'a'; letter <= 'z'; ++letter)
{
int count = counters[letter - 'a'];
if (count > 0)
cout << letter << letter << ' ' << count << ' ';
}
cout << '\n';
Not perfect, but hopefully something to get you started. This is untested code.
You can use an int array of length 26 to keep track of repeated instances of letters. You can then iterate over the C string and check for repeats. If you find one, make sure to jump your iterator forward.
#include <iostream>
#include <cstring>
int main() {
int repeats[26] = {0};
char str[] = "Double bubble deep in the sea of tooth with teeth and meet with riddle.";
for (char *ch = str; *ch; ch++)
*ch = tolower(*ch);
for (char *ch = str; *ch; ch++) {
if (std::isalpha(*ch) && *ch == ch[1]) {
repeats[*ch - 'a']++;
ch++;
}
}
for (size_t i = 0; i < 26; i++) {
std::cout << static_cast<char>('a' + i) << ": " << repeats[i] << std::endl;
}
return 0;
}
Result:
a: 0
b: 1
c: 0
d: 1
e: 3
f: 0
g: 0
h: 0
i: 0
j: 0
k: 0
l: 0
m: 0
n: 0
o: 1
p: 0
q: 0
r: 0
s: 0
t: 0
u: 0
v: 0
w: 0
x: 0
y: 0
z: 0
Related
Elements : a b c
all combinations in such a way:abcabacbcabc
Formula to get total number of combinations of unique elements without repetition = 2^n - 1 (where n is the number of unique elements)
In our case top: 2^3 - 1 = 7
Another formula to get the combinations with specific length = n!/(r! * (n - r)!) (where n= nb of unique items and r=length)
Example for our the above case with r=2 : 3!/(2! * 1!) = 3 which is ab ac bc
Is there any algorithm or function that gets all of the 7 combinations?
I searched a lot but all i can find is one that gets the combinations with specific length only.
UPDATE:
This is what I have so far but it only gets combination with specific length:
void recur(string arr[], string out, int i, int n, int k, bool &flag)
{
flag = 1;
// invalid input
if (k > n)
return;
// base case: combination size is k
if (k == 0) {
flag = 0;
cout << out << endl;
return;
}
// start from next index till last index
for (int j = i; j < n; j++)
{
recur(arr, out + " " + arr[j], j + 1, n, k - 1,flag);
}
}
The best algorithm I've ever find to resolve this problem is to use bitwise operator. You simply need to start counting in binary. 1's in binary number means that you have to show number.
e.g.
in case of string "abc"
number , binary , string
1 , 001 , c
2 , 010 , b
3 , 011 , bc
4 , 100 , a
5 , 101 , ac
6 , 110 , ab
7 , 111 , abc
This is the best solution I've ever find. you can do it simply with loop. there will not be any memory issue.
here is the code
#include <iostream>
#include <string>
#include <math.h>
#include<stdio.h>
#include <cmath>
using namespace std;
int main()
{
string s("abcd");
int condition = pow(2, s.size());
for( int i = 1 ; i < condition ; i++){
int temp = i;
for(int j = 0 ; j < s.size() ; j++){
if (temp & 1){ // this condition will always give you the most right bit of temp.
cout << s[j];
}
temp = temp >> 1; //this statement shifts temp to the right by 1 bit.
}
cout<<endl;
}
return 0;
}
Do a simple exhaustive search.
#include <iostream>
#include <string>
using namespace std;
void exhaustiveSearch(const string& s, int i, string t = "")
{
if (i == s.size())
cout << t << endl;
else
{
exhaustiveSearch(s, i + 1, t);
exhaustiveSearch(s, i + 1, t + s[i]);
}
}
int main()
{
string s("abc");
exhaustiveSearch(s, 0);
}
Complexity: O(2^n)
Here's an answer using recursion, which will take any number of elements as strings:
#include <vector>
#include <string>
#include <iostream>
void make_combos(const std::string& start,
const std::vector<std::string>& input,
std::vector<std::string>& output)
{
for(size_t i = 0; i < input.size(); ++i)
{
auto new_string = start + input[i];
output.push_back(new_string);
if (i + 1 == input.size()) break;
std::vector<std::string> new_input(input.begin() + 1 + i, input.end());
make_combos(new_string, new_input, output);
}
}
Now you can do:
int main()
{
std::string s {};
std::vector<std::string> output {};
std::vector<std::string> input {"a", "b", "c"};
make_combos(s, input, output);
for(auto i : output) std::cout << i << std::endl;
std::cout << "There are " << output.size()
<< " unique combinations for this input." << std::endl;
return 0;
}
This outputs:
a
ab
abc
ac
b
bc
c
There are 7 unique combinations for this input.
output format: string = 7714
0 0
1 1
2 0
3 0 .....
7 2 and so on till digit 9. Note: there will be new line after each digit occurence value. Alongside each digits same occurence is showing up which is 15 or 20 or 25.
#include <iostream>
using namespace std;
int main()
{
string s;
cin>>s;
int i,j;
int c=0;
int a;
int l=s.length();
for(i=0;i<l;i++)
{
cin>>s[i];
}
for(i=0;i<l;i++)
{
for(j=0;j<=9;j++)
{
if(s[j]==1 || s[j]==2 || s[j]==3 || s[j]==4 || s[j]==5 || s[j]==6 || s[j]==7 || s[j]==8 || s[j]==9 || s[j]==0)
{
c++;
}
}
}
for(i=0;i<=9;i++)
{
cout<<i<<" "<<c<<endl;
}
}
Since after one day all the comments and answers so far obviously could not help you, see the following simple solution.
The exercise targets people starting with C++, so I suppose it is better to use basic constructs like arrays and loops.
The array counts holds the counts of the digits, one for each possible digit; so the size of the array is 10. Note that the characters in the string are not integral digits from 0..9, but characters in (very likely) ASCII code from 48..57. The ASCII-code of character '0' is integral value 48, not integral value 0. So to get a range from 0..9, one has to substract 48 (or '0', which is the same as integral 48) from the respective character.
Hope it helps.
#include <iostream>
#include <string>
int main() {
std::string s = "7714";
int counts[10] = { 0 }; // init all the counters with 0
for (int i=0; i<s.length();i++) { // iterate over the characters in s
char c = s[i];
if (isdigit(c)) {
int index = c - '0'; // c is from '0' to '9' (i.e. ASCII codes 48..57); need it from 0..9; char('0') stands for int(49).
counts[index]++; // increment the counter representing the respective digit
} else {
std::cout << "invalid character (not a digit) in s" << std::endl;
}
}
for (int i=0; i<9; i++) {
std::cout << i << ": " << counts[i] << std::endl;
}
}
Output:
0: 0
1: 1
2: 0
3: 0
4: 1
5: 0
6: 0
7: 2
8: 0
The power of algorithms . . .
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
// Get String from user
std::string s; std::cin >> s;
// This is what we want to search
std::string digits("0123456789");
// Do all the work in a one liner
std::for_each(digits.begin(), digits.end(), [&s](const char c) { std::cout << c << ' ' << std::count(s.begin(), s.end(), c) << '\n'; });
return 0;
}
Create an array of counters.
int counters[10]; //will store the counts of each instance.
//counters[0] will count the number of 0s, etc.
Convert each input character to integer.
look up how to do this on the internet.
Increment that index of counters array.
counters[the_converted_character_to_integer]++;
I'm trying to solve problem 8 from project euler but I'm getting way too big numbers as results and I don't know why.
The problem is "Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?"
My code :
#include <iostream>
#include <string>
int main()
{
std::string str = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
long long a = 1;
long long fin = 0;
for (int c = 0; c < 988; c++)
{
for (int d = 0; d < 13; d++)
{
a = a * str.at(c + d);
}
if (a > fin)
{
fin = a;
std::cout << fin << " at " << c << std::endl;
}
a = 1;
}
system("pause");
}
The output :
7948587103611909356 at 0
8818137127266647872 at 15
8977826317031653376 at 71
9191378290313403392 at 214
9205903071867879424 at 573
Press any key to continue...
The problem is that the characters '0' through '9' are not the same as the integers 0 through 9; rather, '0' has the value 48, '1' has the value 49, and so on. (These are the ASCII values of those characters.)
So to convert from a digit character to the desired number — for example, to extract e.g. 3 from '3' — you need to subtract '0'. In other words, you need to change this:
a = a * str.at(c + d);
to this:
a = a * (str.at(c + d) - '0');
I'm working on a simple substitution-cipher decoder. I'm using frequency analysis to decrypt the ciphertext. Just looking at the frequency of unique letter isn't enough. I need to look at the occurrences of 2-letter sequences (maybe 3-letter sequences).
My code for counting the occurrences of each letter is below
int counterRaw[256][2] = {0};
for(int i = 0; i <inputString.length(); i++)
counterRaw[inputString[i]][1]++;
int counterLetter[26][2] = {0};
for(int i = 0 ; i<26 ; i++){
counterLetter[i][0] = 'A'+i;
counterLetter[i][1] = counterRaw['A'+i][1];
As you can see very simple yet effective !
But I don't know how to achieve a 2-letter sequence counter, do you have any idea which could help me to code this ?
Thanks !
EDIT : As an example
Given AZAZ RTYU JKLM I want my program to output :
AZ : 2
ZA : 1
ZR : 1
RT : 1
...
Something like the following would do the trick, though you'd have to do some jiggery pokery to make it suit your own needs.
#include <iostream>
#include <map>
#include <string>
int main ()
{
std::string message("some string that you will probably get from some encrypted file");
std::map<std::string,int> occurences;
std::string seq(" ");
for(int i = 1; i < message.length() - 1; i++)
{
seq[0] = message[i-1];
seq[1] = message[i];
//ignore spaces
if (seq.compare(0,1, " ") && seq.compare(1,1, " "))
{
occurences[seq]++;
}
}
//let's have a look ...
for(auto iter = occurences.begin(); iter != occurences.end(); ++iter)
{
std::cout << iter->first << " " << iter->second << "\n";
}
return 0;
}
output:
ab 1
at 1
ba 1
bl 1
cr 1
ed 1
en 1
et 1
fi 1
fr 1
ge 1
ha 1
il 2
in 1
ll 1
ly 1
me 2
nc 1
ng 1
ob 1
om 3
ou 1
pr 1
pt 1
ri 1
ro 2
ry 1
so 2
st 1
te 1
th 1
tr 1
wi 1
yo 1
yp 1
You should create a "composite letter" from two letters.
As letters in C,C++ are numbers, you can just convert each of the 2 letters to a number ( the characters are already numbers ) and than create a number with two numbers. e.g. int C=inputString[i]+256*inputString[i+1].
The above with the supposition that the strings are of char and chars are between 0 and 255 ( better than signed ).
What you are doing right now is a counting sort.
A radix sort would be a viable option for you if you take multiple digits into consideration.
Here you go (based on the idea of user3723779):
#define MAKEWORD(a, b) (((a) << 8) | (b))
std::string noSpaces(std::string s)
{
int pos;
while((pos = s.find(' ')) != std::string::npos)
{
s.erase(pos, 1);
}
return s;
}
std::map<short, int> seqDet2(const std::string &s)
{
int length = s.length();
if(length == 0) return std::map<short, int>();
// assert(sizeof(char) == 1);
std::vector<short> v;
for(int i = 0; i < length - 1; ++i)
{
v.push_back(MAKEWORD(s[i], s[i + 1]));
}
std::map<short, int> occ;
for(auto x: v)
{
occ[x]++;
}
return occ;
}
int main()
{
std::string s = "AZAZRTYUI AZTWI";
auto occ = seqDet2(noSpaces(s));
for(auto x: occ)
{
unsigned char b = (unsigned char)x.first;
unsigned char a = (unsigned char)(x.first >> 8);
printf("%c%c - %d\n", a, b, x.second);
}
getchar();
}
I'm trying to code an algorithm that will save to file as binary strings every integer in a range. Eg, for the range 0 to 7:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
Note that the leading zeros and spaces between digits are essential.
What I cant figure out how to do in a simple way is to convert the integers to binary numbers represented by bool []s (or some alternate approach).
EDIT
As requested, my solution so far is:
const int NUM_INPUTS = 6;
bool digits[NUM_INPUTS] = {0};
int NUM_PATTERNS = pow(2, NUM_INPUTS);
for(int q = 0; q < NUM_PATTERNS; q++)
{
for(int w = NUM_INPUTS -1 ; w > -1 ; w--)
{
if( ! ((q+1) % ( (int) pow(2, w))) )
digits[w] = !digits[w];
outf << digits[w] << " ";
}
outf << "\n";
}
Unfortunately, this is a bit screwy as the first pattern it gives me is 000001 instead of 000000.
This is not homework. I'm just coding a simple algorithm to give me an input file for training a neural network.
Don't use pow. Just use binary math:
const int NUM_INPUTS = 6;
int NUM_PATTERNS = 1 << NUM_INPUTS;
for(int q = 0; q < NUM_PATTERNS; q++)
{
for(int w = NUM_INPUTS -1 ; w > -1; w--)
{
outf << ((q>>w) & 1) << " ";
}
outf << "\n";
}
Note: I'm not providing code, but merely a hint because the question sounds like homework
This is quite easy. See this example:
number = 23
binary representation = 10111
first digit = (number )&1 = 1
second digit = (number>>1)&1 = 1
third digit = (number>>2)&1 = 1
fourth digit = (number>>3)&1 = 1
fifth digit = (number>>4)&1 = 1
Alternatively written:
temp = number
for i from 0 to digits_count
digit i = temp&1
temp >>= 1
Note that the order of digits taken by this algorithm is the reverse of what you want to print.
The lazy way would be to use std::bitset.
Example:
#include <bitset>
#include <iostream>
int main()
{
for (unsigned int i = 0; i != 8; ++i){
std::bitset<3> b(i);
std::cout << b << std::endl;
}
}
If you want to output the bits individually, space-separated, replace std::cout << b << std::endl; with a call to something like Write(b), with Write defined as:
template<std::size_t S>
void Write(const std::bitset<S>& B)
{
for (int i = S - 1; i >= 0; --i){
std::cout << std::noboolalpha << B[i] << " ";
}
std::cout << std::endl;
}