C++ heap sort of vector<string,int> - c++

I can not figure out where I'm having my problem with my heap sort.
The program takes a filename from the command line, imports the words into a vector then that vector is turned into a vector pair of vector<string,int> where string is the word and int is the count of how many instances of that word are in the file.
The vector<PAIR> is then sorted by either the string (value or v) or by int (key or k). My sorting by Key works fine however sort by value is off. I suspect I'm missing an if statement in max_heapify when sorting by value. Here's my code:
main.cpp
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>
#include <string.h>
#include <stdio.h>
#include <map>
#include <time.h>
#include "readwords.h"
using namespace std;
readwords wordsinfile;
vector<string> allwords;
bool times;
char *filename;
timespec timestart,timeend;
vector< pair<string,int> > allwords_vp;
timespec diffclock(timespec start, timespec end);
int main ( int argc, char *argv[] ) {
filename = argv[1];
//Lets open the file
ifstream ourfile2(filename);
//Lets get all the words using our requirements
allwords = wordsinfile.getwords(ourfile2);
//Convert all the words from file and count how many times they
//appear. We will store them in a vector<string,int> string
//being the word and int being how many time the word appeared
allwords_vp = wordsinfile.count_vector(allwords);
cout << "HeapSort by Values" << endl;
if (times) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timestart);
wordsinfile.heapsort(const_cast<char *>("v"));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timeend);
cout << "HeapSort by Values ran in "
<< diffclock(timestart,timeend).tv_nsec << " nanosecond or "
<< diffclock(timestart,timeend).tv_nsec/1000 << " millisecond"
<< endl;
} else {
wordsinfile.heapsort(const_cast<char *>("v"));
}
cout << "HeapSort by Keys" << endl;
if (times) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timestart);
wordsinfile.heapsort(const_cast<char *>("k"));
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timeend);
cout << "HeapSort by Keys ran in "
<< diffclock(timestart,timeend).tv_nsec << " nanosecond or "
<< diffclock(timestart,timeend).tv_nsec/1000 << " millisecond"
<< endl;
} else {
wordsinfile.heapsort(const_cast<char *>("k"));
}
}
timespec diffclock(timespec start, timespec end) {
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
readwords.h
#ifndef READWORDS_H
#define READWORDS_H
#include <vector>
#include <map>
#include <utility>
#include <time.h>
typedef std::pair<std::string, int> PAIR;
bool isasciifile(std::istream& file);
class readwords {
private:
std::vector<PAIR> vp;
public:
std::vector<std::string> getwords(std::istream& file);
std::vector<PAIR> count_vector(std::vector<std::string> sv);
void print_vectorpair(std::vector<PAIR> vp);
void print_vector(std::vector<std::string> sv);
void heapsort(char how[]);
void buildmaxheap(std::vector<PAIR> &vp, int heapsize, char how[]);
void max_heapify(std::vector<PAIR> &vp, int i, int heapsize, char how[]);
void swap_pair(PAIR &p1, PAIR &p2);
};
readwords.cpp
#include <fstream>
#include <iostream>
#include <map>
#include "readwords.h"
#include <vector>
#include <string>
#include <utility>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
//using std::vector;
using namespace std;
typedef pair<string, int> PAIR;
// Do we have a ASCII file?
// Lets test the second 10 chars to make sure
// This method is flawed if the file is less than 10 chars
bool isasciifile(std::istream& file) {
int c = 0;
bool foundbin = false;
for(c=0; c < 10;c++) {
if(!isprint(file.get())){
// Looks like we found a non ASCII file, or its empty.
foundbin = true;
}
}
return foundbin;
}
// This is our workhorse as it splits up the words based on our criteria and
// passes them back as a vector of strings.
vector<string> readwords::getwords(std::istream& file) {
char c;
string aword;
vector<string> sv;
//Let go through the file till the end
while(file.good()) {
c = file.get();
if (isalnum(c)) {
//convert any uppercase to lowercase
if(isupper(c)) {
c = (tolower(c));
}
//if its a space lets go onto the next char
if(isspace(c)) { continue; }
//everything looks good lets add the char to our word
aword.insert(aword.end(),c);
} else {
//its not a alphnum or a space so lets skip it
if(!isspace(c)) { continue; }
//reset our string and increment
if (aword != "") {sv.push_back(aword);}
aword = "";
continue;
}
}
return sv;
}
vector<PAIR> readwords::count_vector(vector<string> sv) {
unsigned int i = 0;
int j = 0;
int match = 0;
// cout << "Working with these string: " << endl;
// print_vector(sv);
for (i=0; i < sv.size(); i++) {
// cout << "count of i: " << i << " word is: " << sv.at(i) << endl;
match = 0;
if(readwords::vp.size() == 0) {
readwords::vp.push_back(make_pair(sv.at(i),1)); continue;
}
for (j=readwords::vp.size() - 1; j >= 0; --j) {
if (sv.at(i) == readwords::vp.at(j).first) {
// cout << "Match found with: " << sv.at(i) << endl;;
readwords::vp.at(j).second = readwords::vp.at(j).second + 1;
match = 1;
}
// cout << "Value of j and match: " << j << match << endl;
if ( j == 0 && match == 0) {
// cout << "Match found at end with: " << sv.at(i) << endl;;
readwords::vp.push_back(make_pair(sv.at(i),1));
}
}
}
//Prob need to sort by first data type then second here, prior to sort functions.
//Might not be the best place as the sort functions would alter it, if not here
//then each sort requires to do secondary search
return readwords::vp;
}
void readwords::print_vectorpair(vector<PAIR> vp) {
unsigned int i = 0;
for (i=0; i < vp.size(); ++i) {
cout << vp.at(i).first << " " << vp.at(i).second << endl;
}
}
void readwords::print_vector(vector<string> sv) {
unsigned int i = 0;
for (i=0; i < sv.size(); ++i) {
cout << sv.at(i) << endl;
}
}
void readwords::heapsort(char how[]) {
int heapsize = (readwords::vp.size() - 1);
buildmaxheap(readwords::vp, heapsize, how);
for(int i=(readwords::vp.size() - 1); i >= 0; i--) {
swap(readwords::vp[0],readwords::vp[i]);
heapsize--;
max_heapify(readwords::vp, 0, heapsize, how);
}
print_vectorpair(readwords::vp);
}
void readwords::buildmaxheap(vector<PAIR> &vp, int heapsize, char how[]) {
for(int i=(heapsize/2); i >= 0 ; i--) {
max_heapify(vp, i, heapsize, how);
}
}
void readwords::max_heapify(vector<PAIR> &vp, int i, int heapsize, char how[]) {
int left = ( 2 * i ) + 1;
int right = left + 1;
int largest;
if(!strcmp(how,"v")) {
if(left <= heapsize && vp.at(left).second >= vp.at(i).second ) {
if( vp.at(left).first >= vp.at(i).first ) {
largest = left;
} else {
largest = i;
}
} else {
largest = i;
}
if(right <= heapsize && vp.at(right).second >= vp.at(largest).second) {
if( vp.at(right).first >= vp.at(largest).first) {
largest = right;
}
}
}
if(!strcmp(how,"k")) {
if(left <= heapsize && vp.at(left).first > vp.at(i).first) {
largest = left;
} else {
largest = i;
}
if(right <= heapsize && vp.at(right).first > vp.at(largest).first) {
largest = right;
}
}
if(largest != i) {
swap(vp[i], vp[largest]);
max_heapify(vp, largest, heapsize, how);
}
}

The vector is then sorted by either the string (value or v) or by int (key or k).
That description doesn't match the code, sorting with a how parameter of "k" sorts by the first component only, which is the string, and sorting with "v" as how parameter takes both components into account.
I think it's a rather bad idea to pass a char[] to determine the sorting criterion, it should be a comparator function, so you need only one implementation in max_heapify.
My sorting by Key works fine however sort by value is off. I suspect I'm missing an if statement in max_heapify when sorting by value.
The problem is that a heap sort needs a total ordering or it won't sort properly.
Your conditions
if(left <= heapsize && vp.at(left).second >= vp.at(i).second ) {
if( vp.at(left).first >= vp.at(i).first ) {
largest = left;
} else {
largest = i;
}
} else {
largest = i;
}
check whether both components of vp.at(left) (resp. right) are at least as large as the corresponding component of vp.at(i), resulting in the product partial ordering, two general pairs are not comparable, and in that case, your max_heapify doesn't do anything.
Example, for <"a",3>, <"b",2> and <"c",1> in the positions i, left, right, in whichever order, your max_heapify sets largest to i.
If your sorting by "v" is meant to sort based on the int component first, and in case of a tie, take the string component into account, you'd need to distinguish the cases vp.at(left).second > vp.at(i).second and equality (for right too, of course). For example
if(left <= heapsize && vp.at(left).second >= vp.at(i).second ) {
if(vp.at(left).second > vp.at(i).second || vp.at(left).first >= vp.at(i).first ) {
largest = left;
} else {
largest = i;
}
} else {
largest = i;
}

To sort a vector<pair<string, int> > by values, consider adding vector<pair<int, string> >
vector<pair<int, string> > v(orignal.size());
for (int i = 0; i < v.size(); ++i) v[i] = make_pair(original[i].second, original[i].first);
sort(v.begin(), v.end());

Related

Experiencing a segmentation fault inconsistently with my implementation of a hash table with linear probing

Trying to implement a hash table with linear probing for a project but I am running into a few issues, where I think one of them is the main culprit.
For starters, after compiling the code, if I were to run the program 10 times in a row, I would experience a segmentation fault: 11 around 2/3 of the time.
When the code does actually run, it seems to "mostly" work. indicies 9500-10000 are perfect with all slots filled. But when continuing down(9000-9500), more than 10 NULL spaces are seen and there are some slots filled with bogus values, ie. value > 100,000.
I am using a dataset of 10,000 integers from a csv file all with values < 100,000. I was going to try to debug this using GDB and core however my computer isn't too pleased with my installing it at the moment.
#ifndef HASHLINEAR_HPP
#define HASHLINEAR_HPP
struct node{
int key;
};
class HashLinear{
struct node** table;
int tableSize;
int numCollisions = 0;
public:
HashLinear(int bsize);
void insert(int key);
unsigned int hashFunction(int key);
int search(int key);
int getCollisions();
void printTable();
};
#endif
#include "hashlinear.hpp"
#include <iostream>
using namespace std;
HashLinear::HashLinear(int bsize){
this->tableSize = bsize;
table = new node*[tableSize];
for(int i = 0; i < tableSize; i++){
table[i] = NULL;
}
}
int HashLinear::getCollisions(){
return numCollisions;
}
unsigned int HashLinear::hashFunction(int key){
return key % tableSize;
}
void HashLinear::insert(int key){
node* newNode = new node;
newNode->key = key;
int index = hashFunction(key);
while(table[index] != NULL && table[index]->key != key){
numCollisions++;
index = (index + 1) % tableSize;
}
table[index] = newNode;
}
int HashLinear::search(int key){
int value = hashFunction(key);
int num = 0;
while(table[value] != NULL){
num = 0;
if(num++ > tableSize){
break;
}
if(table[value]->key == key){
return value;
}
value++;
value %= tableSize;
}
return -1;
}
void HashLinear::printTable(){
for(int i = 0; i < tableSize; i++){
cout << i << " || ";
if(table[i] == NULL){
cout << "NULL" << endl;
}
else{
cout << table[i]->key << endl;
}
}
}
#include "hashlinear.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <time.h>
#include <stdlib.h>
#include <chrono>
using namespace std;
int main(){
//******Read in data******//
int testData[10000];
float insertTime[100];
float searchTime[100];
int index = 0;
string line, temp, word;
ifstream inputFile;
inputFile.open("dataSetA-updatedhashlinear.csv");
if(inputFile.fail()){
cout << "Could not open data." << endl;
return -1;
}
else{
while(inputFile >> temp){
getline(inputFile, temp);
stringstream inStream(temp);
while(getline(inStream, word, ',')){
testData[index] = stoi(word);
index++;
}
}
inputFile.close();
}
//******Read in data******//
//cout << "Printing random data in range of 0 ~ 10: " << testData[rand() % 10 + 0] << endl;
//******Insert/Search data in Linked List******//
HashLinear table(10009);
int hashIndex = 0;
int insertTimeIndex = 0;
int searchTimeIndex = 0;
int num = 0;
int upperIndex = 99;
while(hashIndex < 10009){
//Block for 100 insertions
auto insertionStart = chrono::steady_clock::now();//Insert time start
for(int i = hashIndex; i < upperIndex; i++){ //Keep track of current index as well as an upper index to control amount of inserts
table.insert(testData[i]);
hashIndex++;
}
auto insertionEnd = chrono::steady_clock::now();
insertTime[insertTimeIndex] = chrono::duration_cast<chrono::microseconds>(insertionEnd - insertionStart).count() / 100.0;//Insert time end
insertTimeIndex++;
//Block for 100 insertions
//Block for 100 searches
num = 0;
auto searchStart = chrono::steady_clock::now();//Search time start
while(num < 100){ //Do 100 random searches from 0 index to upperindex
srand((unsigned)time(0));
int searchNode = table.search(testData[rand() % upperIndex + 0]);
num++;
}
auto searchEnd = chrono::steady_clock::now();
searchTime[searchTimeIndex] = chrono::duration_cast<chrono::microseconds>(searchEnd - searchStart).count() / 100.0;//Search time end
searchTimeIndex++;
//Block for 100 searches
upperIndex += 100;
}
//******Insert/Search data in Linked List******//
//******TESTING******//
table.printTable();
cout << "Search time: " << searchTime[20] << endl;
cout << "Insert time: " << insertTime[20] << endl;
cout << "Collisons: " << table.getCollisions() << endl;
int testIndex = table.search(34262);
cout << "Index of 34262: " << testIndex << endl;
//******TESTING******//
}
So after some more debugging I figured out I am just slow. I was iterating 100 times past the end of the testData array creating bogus values and making the hash table not fill correctly.

How can i check if all charterers in a word are existing into the other one?

I'm trying to make a code that takes tow words from user and store them as arrays and check if the first word's all characters are already exists in the second word , if Yes then just output Yes , if NO then output a NO .
Example :
input :
ENTER THE FIRST WORD :
fos
ENTER THE SECOND WORD :
stackoverflow
output :
YES
my code is not even close to what i actually want , but i will put it down maybe it will explain what I`m trying to do .
#include <iostream>
#include <string>
using namespace std;
int main() {
char N1[7];
char N2[10];
cout << ("ENTER THE FIRST WORD : ") ;
cin >> N1;
cout <<("ENTER THE SECOND WORD : ");
cin >> N2;
for (int i = 0; i <4; i++)
{
for (int j = 0; j < 7; j++)
{
if (N1[i] = N2[j])
{
cout << ("YES") << endl;
}
else
{
cout << ("NO") << endl;
}
}
}
return 0;
}
Thanks in advance .
I tried it with simple search and 1 boolean variable to track if it is found or not.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "fosq";
string s2 = "stackoverflow";
bool isfound;
for(int i=0;i<s1.length();i++)
{
isfound=false;
for(int j=0;j<s2.length();j++)
{
if(s1[i]==s2[j])
{
isfound=true;
break;
}
}
if(!isfound)
{
cout<<"Not found";
break;
}
}
if(isfound)
{
cout<<"Yes\n";
}
}
Here what I am doing is that I am looping over both strings, comparing each element. If we can not find any element, I just break the search there, if we find all the elements, we simply just output Yes.
I'm not c++ expert but look like you want to check if all char are in the second string - so you better add booleans to your code as:
for (int i = 0; i <4; i++) {
bool charFound = false;
for (int j = 0; j < 7; j++) {
charFound = charFound || (N1[i] == N2[j]); // use OR operator so if found one match it is will stay true
}
if (!charFound) {
cout << ("NO") << endl;
return; // one char is missing - print no and exit
}
}
cout << ("YES") << endl; // if got here you found all char - YES
Also notice the == instead of the = in your code (N1[i] == N2[j]) as in Aziuth's comments
I think the most efficient way is to sort the two arrays before computing the match:
#include <iostream>
#include <algorithm>
#include <array>
template <typename T1, typename T2>
bool match(T1& arr1, T2& arr2) {
for (char c2: arr2) {
for (char c1: arr1) {
if (!c1 || !c2) continue;
if (c1 == c2) break;
if (c1 > c2) return false;
}
}
return true;
}
int main() {
std::array<char, 14> arr1 {"stackoverflow"};
std::array<char, 4> arr2 {"fos"};
std::sort(arr1.begin(), arr1.end());
std::sort(arr2.begin(), arr2.end());
if (match(arr1, arr2)) {
std::cout << "YES" << std::endl;
} else {
std::cout << "NO" << std::endl;
}
return 0;
}

I wrote a bin_search with STL, but these is a small BUG

these is no problems in function generate, and getData
while debug bin_search() the program failed
it seems like that in function bin_search,
using a invalid iterator to the vector
debug in VS2015, find out the in main() function , after bin_search()
value of pos still unknow.
I don't know how to figure it
#include<iostream>
#include <cstdio>
#include <fstream>
#include <ctime>
#include <cstdlib>
#include <vector>
using namespace std;
using RANK = vector<int>::iterator;
const int RANGE = 1000;
const int SIZE = 50;
void generate(ofstream& of) {
srand(static_cast<unsigned> (time(nullptr)));
for (int i = 0; i < SIZE; ++i)
of << static_cast<int> (rand() % RANGE) << endl;
}
void getData(ifstream& ifs, vector<int> &v) {
int tmp;
while(ifs >> tmp)
v.push_back(tmp);
}
RANK bin_search(vector<int> &v, int key, RANK low, RANK high) {
RANK e = v.end();
// if (*mid == key)
// return mid;
// else if (*mid < key)`
// bin_search(v, key, low, mid);
// else if (*mid > high)
// bin_search(v, key, ++mid, high);
// return nullptr;
while (low < high) {
RANK mid = v.begin() + v.size() / 2;
if (*mid == key)
return mid;
else if (*mid < key)
low = mid;
else if (*mid > key)
high = ++mid;
}
return e;
}
int main(int argc, char const *argv[]) {
ofstream ofs("data", ios::out);
generate(ofs);
vector<int> arr;
ifstream ifs("data", ios::in);
getData(ifs, arr);
int value;
cout << "pls enter num to find: " << endl;
cin >> value;
RANK pos = bin_search(arr, value, arr.begin(), arr.end());
cout << *pos << endl;
// if (pos == arr.end())
// cout << "data " << value << "not find." << endl;
// else {
// cout << "data at " << distance(arr.begin(), pos) << endl;
// }
getchar();
return 0;
}
How do you know the array is sorted before you apply binary search? All arrays must be sorted before doing binary search.
void generate(ofstream& of) {
srand(static_cast<unsigned> (time(nullptr)));
for (int i = 0; i < SIZE; ++i)
of << static_cast<int> (rand() % RANGE) << endl;
}
In this function you generate a series of random numbers which you then attemp to apply binary search to that array. Binary search works by doing a logarithmic series of comparisons on a sorted array of numbers to find the item in the array or to say the item cannot be found (or between which numbers it would exist if it could be found).
If the array is unsorted, as it appears to be in this case because the numbers in the array are generated by srand and even it is not that bad at generating random numbers, the binary search's invariant is never met and the best we can do is searching linearly through the array.

least number of digits without duplicates

I am a C++ noob. I have a list of numbers that I put into a Vector. All numbers are 9 digit integers and are unique. I want to know what is the least amount of digits (starting from the right) that can be used to uniquily identify each number in the set. right now there are only 6 numbers, but the list could potentially grow into the thousands. I have posted my code thus far (not working.)
EDIT output is the following...
digit is 1
digit is 1
digit is 1
RUN FINISHED; exit value 0; real time: 0ms; user: 0ms; system: 0ms
This is mostly a learning exercise. Please be generous and explicit with your comments and solutions.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <algorithm>
using namespace std;
int main() {
//declare stream variable and load vector with values
ifstream myfile("mydata.txt");
vector<int> myVector;
int num;
while (myfile >> num) {
myVector.push_back(num);
}
//sort and squack if there is a duplicate.
std::sort(myVector.begin(), myVector.end());
for (int i = 0; i < (myVector.size() - 1); i++) {
if (myVector.at(i) == myVector.at(i + 1)) {
printf("There are duplicate student numbers in the file");
exit(EXIT_FAILURE);
}
}
//if it get here, then there are no duplicates of student numbers
vector<int> newv;
int k = 1;
bool numberFound = false;
bool myflag = false;
while (numberFound == false) {
//loop through original numbers list and add a digit to newv.
for (int j = 0; j < myVector.size(); ++j) {
newv.push_back(myVector.at(j) % (10^k));
}
sort(newv.begin(), newv.end());
for (int i = 0; i < (newv.size() - 1); i++) {
if (newv.at(i) == newv.at(i + 1)) {
//there is a duplicate for this digit. Set flag.
myflag = true;
}
if (myflag == false) {
numberFound = true;
cout << "digit is " << k << endl;
} else {
k++;
}
}
}
// for (int i = 0; i < myVector.size(); i++) {
// cout << "||" << myVector.at(i) << "||" << endl;
// }
//
// for (int i = 0; i < newv.size(); i++) {
// cout << "---" << newv.at(i) << "---" << endl;
// }
return 0;
}
Check the below code.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <math.h>
using namespace std;
int main() {
//declare stream variable and load vector with values
ifstream myfile("mydata.txt");
vector<int> myVector;
int num;
while (myfile >> num) {
myVector.push_back(num);
}
//sort and squack if there is a duplicate.
std::sort(myVector.begin(), myVector.end());
for (int i = 0; i < (myVector.size() - 1); i++) {
if (myVector.at(i) == myVector.at(i + 1)) {
printf("There are duplicate student numbers in the file");
exit(EXIT_FAILURE);
}
}
//if it get here, then there are no duplicates of student numbers
vector<int> newv;
int k = 1;
bool numberFound = false;
bool myflag = false;
int p = 1;
while (numberFound == false) {
//loop through original numbers list and add a digit to newv.
newv.clear();
p = p * 10;
for (int j = 0; j < myVector.size(); ++j) {
newv.push_back(myVector[j] % p);
}
sort(newv.begin(), newv.end());
myflag = false;
for (int i = 0; i < (newv.size() - 1); i++) {
if ( newv[i] == newv[i+1]) {
//there is a duplicate for this digit. Set flag.
myflag = true;
break;
}
}
if (myflag == true){
k ++;
}else{
numberFound = true;
cout << "digit is " << k << endl;
break;
}
}
return 0;
}
Sample Input:
123451789
123456687
125456789
123456780
Output:
digit is 4

Counting the number of occurrences of a string within a string

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;
}