Counting the number of occurrences of a string within a string - c++

What's the best way of counting all the occurrences of a substring inside a string?
Example: counting the occurrences of Foo inside FooBarFooBarFoo

One way to do is to use std::string find function:
#include <string>
#include <iostream>
int main()
{
int occurrences = 0;
std::string::size_type pos = 0;
std::string s = "FooBarFooBarFoo";
std::string target = "Foo";
while ((pos = s.find(target, pos )) != std::string::npos) {
++ occurrences;
pos += target.length();
}
std::cout << occurrences << std::endl;
}

#include <iostream>
#include <string>
// returns count of non-overlapping occurrences of 'sub' in 'str'
int countSubstring(const std::string& str, const std::string& sub)
{
if (sub.length() == 0) return 0;
int count = 0;
for (size_t offset = str.find(sub); offset != std::string::npos;
offset = str.find(sub, offset + sub.length()))
{
++count;
}
return count;
}
int main()
{
std::cout << countSubstring("FooBarFooBarFoo", "Foo") << '\n';
return 0;
}

You should use KMP Algorithm for this.
It solves it in O(M+N) time where M and N are the lengths of the two strings.
For more info-
https://www.geeksforgeeks.org/frequency-substring-string/
So what KMP Algorithm does is, it search for string pattern. When a pattern has a sub-pattern appears more than one in the sub-pattern, it uses that property to improve the time complexity, also for in the worst case.
The time complexity of KMP is O(n).
Check this out for detailed algorithm:
https://www.geeksforgeeks.org/kmp-algorithm-for-pattern-searching/

#include <iostream>
#include<string>
using namespace std;
int frequency_Substr(string str,string substr)
{
int count=0;
for (int i = 0; i <str.size()-1; i++)
{
int m = 0;
int n = i;
for (int j = 0; j < substr.size(); j++)
{
if (str[n] == substr[j])
{
m++;
}
n++;
}
if (m == substr.size())
{
count++;
}
}
cout << "total number of time substring occur in string is " << count << endl;
return count;
}
int main()
{
string x, y;
cout << "enter string" << endl;
cin >> x;
cout << "enter substring" << endl;
cin >> y;
frequency_Substr(x, y);
return 0;
}

#include<iostream>
#include<string>
using namespace std;
int main()
{
string s1,s2;
int i=0;
cout<<"enter the string"<<endl;
getline(cin,s1);
cout<<"enter the substring"<<endl;
cin>>s2;
int count=0;
string::iterator it=s1.begin();
while(it!=s1.end())
{
if(*it==s2[0])
{
int x =s1.find(s2);
string subs=s1.substr(x,s2.size());
if(s2==subs)
count++;
}
++it;
}
cout<<count<<endl;
return 0;
}

Related

Why is it that my code is only showing the last element in the array even though It should be showing the element with the most amount of characters

#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
vector<string> createvector() {
vector<string> words;
string names;
cout << "Please enter 5 different words: " << endl;
for (int i = 0; i < 5; i++) {
cin >> names;
words.push_back(names);
}
return (words);
}
void mostchar(vector<string> words) {
string w1 = words[0];
string largestword;
for (int i = 1; i < 5; i++) {
if (words[i] > w1) {
largestword = words[i];
}
}
cout << "The largest word is: " << largestword;
}
int main()
{
vector<string> words;
string names;
words = createvector();
mostchar(words);
}
I do not understand why it's picking the last element or the second to last element every time. Right I've tried to change for(int i = 1; i < 5; i++) but it makes no difference to what I do.
For starters you are comparing strings in the lexicographical order.
if (words[i] > w1) {
Secondly you always comparing with the word in the first element of the array
if (words[i] > w1) {
and the variable w1 is not being changed within the loop. So any last element in the vector that is greater than w1 will be assigned to the variable largestword.
Using the for loop the function can look the following way
void mostchar( const std::vector<std::string> &words )
{
size_t largestword = 0;
for ( size_t i = 1; i < words.size(); i++ )
{
if ( words[largestword].size() < words[i].size() )
{
largestword = i;
}
}
if ( largestword != words.size() )
{
std::cout << "The largest word is: " << words[largestword] << '\n';
}
}
Pay attention to that in general case the user can pass to the function an empty vector. You must check such a possibility within the function.
Bear in mind that there is standard algorithm std::max_element that can be used instead of manually written for loop.
For example
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
void mostchar( const std::vector<std::string> &words )
{
auto largestword = std::max_element( std::begin( words ), std::end( words ),
[]( const auto &a, const auto &b )
{
return a.size() < b.size();
} );
if ( largestword != std::end( words ) )
{
std::cout << "The largest word is: " << *largestword << '\n';
}
}
There are a couple issues here:
1: You should use something like .length() to compare "length"
2: You are comparing the next word in the array to words[0] every time.
EDIT: To further explain this, there is an assignment of string w1 = words[0];. w1 is then used in the if in the for loop here:
string w1 = words[0];
string largestword;
for (int i = 1; i < 5; i++) {
if (words[i] > w1) {
largestword = words[i];
}
}
resulting in the value of words[0] being the value repeatedly compared in the loop.
Adjust the comparison line to if (words[i].length() > largestword.length()) and that solves both problems. You can elminate w1 entirely this way as well.
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
vector<string> createvector() {
vector<string> words;
string names;
cout << "Please enter 5 different words: " << endl;
for (int i = 0; i < 5; i++) {
cin >> names;
words.push_back(names);
}
return (words);
}
void mostchar(vector<string> words) {
string largestword;
for (int i = 0; i < 5; i++) {
if (words[i].length() > largestword.length()) {
largestword = words[i];
}
}
cout << "The largest word is: " << largestword;
}
int main()
{
vector<string> words;
string names;
words = createvector();
mostchar(words);
}

Is there a way to write the same code without using void functions?

I'm a C++ beginner, and I was wondering how I can rewrite this code without using void functions, and use it all in main().
I know that this program needs to get the longest consecutive substring in a string,
but is there another way to do it without using functions?
substring in C++
#include <iostream>
using namespace std;
void longestConsecutivecharacter(string letters){
int finalResult = 1;
int letterCounter = 1;
char flcrcs;
for (int i = 1; i < letters.size(); i++) {
if (letters[i] == letters[i + 1]) {
++letterCounter;
}
else {
if(letterCounter>finalResult)
flcrcs=letters[i-1];
finalResult = max(finalResult, letterCounter);
letterCounter = 1;
}
}
finalResult = max(finalResult, letterCounter);
for(int i=0;i<finalResult;i++)
cout<<flcrcs;
};
int main(){
string letters;
cout << "Enter a string: ";
cin>>letters;
cout << "The first longest consecutive repeating character substring is: ";
longestConsecutivecharacter(letters);
return 0;
}
Why do you want to do it without functions? This method is better and more portable.
If you still want to, you can just take the code and put it in main, like this:
int main(){
string letters;
cout << "Enter a string: ";
cin>>letters;
int finalResult = 1;
int letterCounter = 1;
char flcrcs;
for (int i = 1; i < letters.size(); i++) {
if (letters[i] == letters[i + 1]) {
++letterCounter;
}
else {
if(letterCounter>finalResult) {
flcrcs=letters[i-1];
finalResult = max(finalResult, letterCounter);
letterCounter = 1;
}
}
finalResult = max(finalResult, letterCounter);
for(int i=0;i<finalResult;i++)
cout << "The first longest consecutive repeating character substring is: ";
cout<<flcrcs;
};

I am trying to add large numbers using arrays without using bigint or anything like that. C++

I am trying to add large numbers using arrays without using bigint or anything like that. I can get my program to add the two arrays. However, I need to take the addition of the arrays and output the correct answer like a regular number. I cannot seem to make an algorithm to take the sum of my arrays and ouptut the answer. Does anybody have any tips or suggestions?
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
#include <iterator>
using namespace std;
const int DIGITS = 20;
void readNum(int list[], int& length, string input1);
void reverseArray(int arr[], int start, int end);
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2);
int main()
{
// Write your main here
string input1;
string input2;
int list[DIGITS];
int list2[DIGITS];
int total[DIGITS];
int input1Length;
int input2Length;
cout << "Please enter your 1st number: " << endl;
cin >> input1;
cout << "Please enter your 2nd number: " << endl;
cin >> input2;
input1Length = input1.length();
input2Length = input2.length();
readNum(list, input1Length, input1);
readNum(list2, input2Length, input2);
reverseArray(list, 0, input1Length);
reverseArray(list2, 0, input2Length);
sumNum(list, input1Length, list2, input2Length);
}
void readNum(int list[], int& length, string input1)
{
int array[DIGITS];
for (int i = 0; i < length; i++)
{
array[i] = input1[i] - '0';
list[i] = array[i];
}
}
void reverseArray(int arr[], int start, int length)
{
int end;
end = length - 1;
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2)
{
int length;
int sum = 0;
int carry = 0;
int total[DIGITS];
if (numOfElementsList1 > numOfElementsList2)
{
length = numOfElementsList1;
}
else
{
length = numOfElementsList2;
}
for (int i = 0; i < length; i++)
{
sum = list1[i] + list2[i] + carry;
if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
{
carry = 0;
}
total[i] = sum;
cout << total[i];
}
}
Strings are arrays of characters, you could just use them as-is. The advantage being... they're just strings, and you can output them as a string just as easily. Not a new technique, it's called a binary coded decimal which in this case is a zoned BCD (where the zone is 0x30 in ASCII, or zone 0xF0 in EBCDIC).
#include <iostream>
#include <string>
#include <stdexcept>
using std::string;
using std::cout;
using std::cin;
using std::runtime_error;
static string sumNum(string, string);
int main() {
string input1;
string input2;
cout << "Please enter your 1st number: ";
cin >> input1;
cout << "Please enter your 2nd number: ";
cin >> input2;
auto sum = sumNum(input1, input2);
cout << "Sum is: " << sum << "\n";
}
string sumNum(string a, string b) {
//a = string(a.rbegin(), a.rend());
//b = string(b.rbegin(), b.rend());
string sum;
auto digit = [carry = 0](int value) mutable {
value += carry;
if (value > 9) {
carry = 1;
value -= 10;
} else {
carry = 0;
}
return static_cast<char>(value + '0');
};
auto num = [](char c) {
if (c < '0' || c > '9') {
throw runtime_error("not a digit");
}
return c - '0';
};
auto aa = a.rbegin();
auto bb = b.rbegin();
while(aa != a.rend() && bb != b.rend()) {
sum.push_back(digit((num(*aa)) + (num(*bb))));
++aa;
++bb;
}
while (aa != a.rend()) {
sum.push_back(digit(num(*aa)));
++aa;
}
while (bb != b.rend()) {
sum.push_back(digit(num(*bb)));
++bb;
}
char last = digit(0);
if (last != '0')
sum.push_back(last);
return string(sum.rbegin(), sum.rend());
}

Return all codes - String

Assume that the value of a = 1, b = 2, c = 3, ... , z = 26. You are given a numeric string S. Write a program to return the list of all possible codes that can be generated from the given string.
For most of the cases this code works but it gives wrong output for inputs which have numbers greater than 26. For eg: 12345.
#include <iostream>
#include <string.h>
using namespace std;
using namespace std;
int atoi(char a)
{
int i=a-'0';
return i;
}
char itoa(int i)
{
char c='a'+i-1;
return c;
}
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
return 1;
}
if(input.size()==1)
{
output[0]=output[0]+itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
for(int i=0;i<size1;i++)
{
output[i]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[i+size1]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return size1+size2;
}
int main(){
string input;
cin >> input;
string output[10000];
int count = getCodes(input, output);
for(int i = 0; i < count && i < 10000; i++)
cout << output[i] << endl;
return 0;
}
if i give input 12345, the output is:
"
abcde
awde
lcde
l"
instead of :
"
abcde
awde
lcde"
i got it fellow members. i did not initialised the size2 variable to zero. also i didn't use >= operator.
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
output[0]="";
return 1;
}
if(input.size()==1)
{
output[0]=itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2=0;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>=10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
int k=0;
for(int i=0;i<size1;i++)
{
output[k++]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[k++]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return k;
}
this is the final code for getCodes function. Thanks everyone :)
You can do that more simply with something like this:
#include <utility>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
void getCodesRec(unsigned int num, string& current, vector<string>& result)
{
// First and last chars for the codes
static constexpr char FIRST_CHAR = 'a';
static constexpr char LAST_CHAR = 'z';
if (num == 0)
{
// When there is no more number add the code to the results
result.push_back(current);
}
else
{
// Add chars to the existing code
unsigned int next = num;
unsigned int rem = next % 10;
unsigned int f = 1;
// While we have not gone over the max char number
// (in practice this loop will run twice at most for a-z letters)
while (next > 0 && rem <= (unsigned int)(LAST_CHAR - FIRST_CHAR) + 1)
{
next = next / 10;
if (rem != 0) // 0 does not have a replacement
{
// Add the corresponding char
current.insert(0, 1, FIRST_CHAR + char(rem - 1));
// Recursive call
getCodesRec(next, current, result);
// Remove the char
current.erase(0, 1);
}
// Add another number
f *= 10;
rem += f * (next % 10);
}
}
}
vector<string> getCodes(unsigned int num)
{
vector<string> result;
string current;
getCodesRec(num, current, result);
return result;
}
int main()
{
unsigned int num = 12345;
vector<string> codes = getCodes(12345);
cout << "Codes for " << num << endl;
for (string& code : codes)
{
cout << "* " << code << endl;
}
return 0;
}
Output:
Codes for 12345
* abcde
* lcde
* awde

Determine if all characters in a string are unique in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Trying to implement a fairly simple program in C++. I'm kinda new to this language. But it doesn't seem to be working.
#include <iostream>
#include <string>
using namespace std;
bool isUnique(string);
int main(){
bool uniq;
string a;
cout << "Please input a string, not a very long one...."<< endl;
getline(cin, a);
uniq = isUnique(a);
if (uniq == true)
{
cout << "The string has no repeatations." <<endl;
}else{
cout << "The characters in the string are not unique." <<endl;
}
return EXIT_SUCCESS;
}
bool isUnique(string str){
int len = strlen(str);
bool uniq = true;
for (int i = 0; i <= len; ++i)
{
for (int j = i+1; j <= len; ++j)
{
if (str[j] == str[i])
{
uniq = false;
}
}
}
return uniq;
}
The program compiles but has some logical errors I suppose. Any help appreciated.
An simple criterion for uniqueness is that there are no repeated characters in the sorted range of characters. There are algorithms in the standard library for this:
#include <algorithm> // for std::sort, std::unique
#include <iostream> // for std::cin, std::cout
#include <string> // for std:getline, std::string
int main()
{
std::string input;
std::cout << "Please input a string, not a very long one: ";
std::getline(input, std::cin);
std::sort(input.begin(), input.end());
bool u = std::unique(input.begin(), input.end()) == input.end();
if (u) { std::cout << "Every character is unique.\n"; }
else { std::cout << "The string contains repeated characters.\n"; }
}
As an optimization, you can exit early if the string has more characters than there are unique characters, though you'd need some way to determine what that number is.
You can check uniqueness much easier without a nested loop: make an array of bool[256], cast char to unsigned char, and use as an index into the array. If a bool has been set, the characters are not unique; otherwise, they are unique.
bool seen[256];
for (int i = 0 ; i != str.length() ; i++) {
unsigned char index = (unsigned char)str[i];
if (seen[index]) return false;
seen[index] = true;
}
return true;
The idea is simple: you mark characters that you've seen as you go, returning false if you see a "marked" character. If you reach the end without returning, all characters are unique.
This algorithm is O(n); your algorithm is O(n2). This does not make much difference, though, because it is impossible to construct a string of unique characters that is longer than 256 characters.
You are using a string, so it is not necessary to convert it to a char array. Use the string to check. You can check it like this:
bool isUnique(string str){
for (std::string::size_type i = 0; i < str.size(); ++i)
{
if(i < str.size()-1){
for (std::string::size_type j = i+1; j < str.size(); ++j)
{
if (str[j] == str[i])
{
uniq = false;
}
}
}
}
return uniq;
}
you can try this:
int main () {
bool uniqe=false;
string a;
char arr[1024];
int count[256]={0};
cout << "Please input a string, not a very long one...."<< endl;
getline(cin, a);
strcpy(arr, a.c_str());
for(int i=0;i<strlen(arr);i++)
count[(int)(arr[i])]++; // counting the occurence of character
for(int i=0;i<256;i++){
if(count[i]>1){ // if count > 1 means character are repeated.
uniqe=false;
break;
}else{
uniqe=true;
}
}
if(uniqe)
cout << "The string has no repeatations." <<endl;
else
cout << "The characters in the string are not unique." <<endl;
return 0;
}
There are too many errors in your code. For example instead of
int len = sizeof(arr)/sizeof(*arr);
there shall be
size_t len = std::strlen( arr );
Or instead of
for (int i = 0; i <= len; ++i)
there shall be at least
for (int i = 0; i < len; ++i)
and so on.
And there is no any need to define a character array. Class std::string has all that is required to do the task.
Try the following function
bool isUnique( const std::string &s )
{
bool unique = true;
for ( std::string::size_type i = 0; i < s.size() && unique; i++ )
{
std::string::size_type j = 0;
while ( j < i && s[j] != s[i] ) ++j;
unique = j == i;
}
return unique;
}
Here is a demonstrative program
#include <iostream>
#include <iomanip>
#include <string>
bool isUnique( const std::string &s )
{
bool unique = true;
for ( std::string::size_type i = 0; i < s.size() && unique; i++ )
{
std::string::size_type j = 0;
while ( j < i && s[j] != s[i] ) ++j;
unique = j == i;
}
return unique;
}
int main()
{
std::string s( "abcdef" );
std::cout << std::boolalpha << isUnique( s ) << std::endl;
s = "abcdefa";
std::cout << std::boolalpha << isUnique( s ) << std::endl;
return 0;
}
The output is
true
false
Here is your code with the errors fixed:
#include <iostream>
using namespace std;
bool isUnique(string,int); //extra parameter
int main(){
bool uniq;
string a;
cout << "Please input a string, not a very long one...."<< endl;
getline(cin, a);
uniq = isUnique(a,a.length()); //pass length of a
if (uniq == true)
{
cout << "The string has no repeatations." <<endl;
}else{
cout << "The characters in the string are not unique." <<endl;
}
return EXIT_SUCCESS;
}
bool isUnique(string str,int len){
bool uniq = true;
for (int i = 0; i < len-1; ++i) //len-1 else j would access unitialized memory location in the last iteration
{
for (int j = i+1; j < len; ++j) //j<len because array index starts from 0
{
if (str[j] == str[i])
{
uniq = false;
}
}
}
return uniq;
}