String's character delete & Frequency without using library - c++

I am trying to work on a assignment which need to input two string S & str and then deliver three results (Without using any string library):
1.Determine the number and positions of the given str in S
2.Return S with any possible occurrence of str removed
ex. if S=aababacd cdefgh ,
str=aba
The Frequency is 2, position is <0,2>
The Character Delete would be cd cdefgh
Attached code is what I have done so far, I can output the Frequency and the position, but now I have few unsolved questions and I have no idea how to implement it.
1.Once I input a string with space in there, ex. abcd efg, the code will implement it immediately, it will not consider abcd efg as one string but consider it as S=abcd and str=efg , with this problem I cant input a string with blank space to test.
2.How can I output the position like this form: <0,2> , because I am using a loop to output the result so it cant not be like that, I was thinking whether I can create an array to store i and then cout it, but I failed.
3.About the character Delete problem, I found one similar problem, it said if I know how to use strcpy without using library then I would know, but I learned it and I still dont know how to handle this question, I know I can compare these two strings but I dont know how to output S without the str part.I was thinking to change the S into '\0' after loop and output it, but that was totally wrong.
I would be really appreciated if anyone could give me some advice, thank you!
#include <iostream>
#include <algorithm>
using namespace std;
void CharacterDelete(){
char S[100], str[100];
bool match =true;
cout << "Enter string S :";
cin >> S;
cout << "Enter string str :";
cin>>str;
for(int i=0; S[i]!='\0'; i++)
{
for(int j=0; str[j]!='\0';j++){
if(S[i+j]!=str[j]){
match=false;
break;
}
if(match){
S[i+j]='\0';
}
}
}
cout<<S;//Apparently thats a wrong solution
}
void Frequency(){
string S,str;
cout<<"Please input string S"<<endl;
cin>>S;
cout<<"Please input string str"<<endl;
cin>>str;
int sum=0;
for (int i=0; i<S.size(); i++)
{
if (i + str.size() > S.size()) break;
bool match=true;
for (int j=0; j<str.size(); j++)
if (S[i+j] != str[j])
{
match=false;
break;
//Once we print blank space and it would implement it immediately?
}
if(match)
{
sum++;
cout<<"Start from"<<i<<endl;
//What if we use an array to store it and then output it?but how to write it?
}
}
cout<<"The Frequency is "<<sum<<endl;
if(sum==0){
cout<<"There is no starting point"<<endl;
}
}
int main() {
Frequency();
CharacterDelete();
return 0;
}

You are using local variables S and str. You need to use S and str in main function. Then transfer this variables from main in Frequency() and CharacterDelete.
Delete characters: create new variable then copy there characters without delete-characters.
Output:
cout << "<" << num_word << ", " << number << ">\n";

Related

check if value inside array already exists

Im a beginner to C++. Its my first year in college. Im completely stuck at this.I have to make a program which takes input 4 strings then check if some value already exists if it does then output value exists and thats it, if not, if they all are unique(all 4 strings) then output them in ascending order.Code bellow works and it already outputs them in ascending order, but how to find if values repeats before writing them?
sorry for my bad English guys i hope u understand what I am trying to say here
string name[4];
string temp;
for(int i=0;i<4;i++){
cout<<"Enter "<<i+1<<" string"<<endl;
getline(cin,name[i]);
}
for(int i=0;i<4;i++){
for(int j=i+1;j<4;j++){
if(name[i]>name[j]){
temp=name[i];
name[i]=name[j];
name[j]=temp;
}
}
}
for(int i=0; i<4; i++){
cout<<name[i]<< " ";
}
You could use the string comparison to check it before pushing it. This is if you want to check that the string is unique, not if you have shared words within each string (which is slightly more complicated.
string name[4];
string temp;
for(int i=0;i<4;i++)
{
cout<<"Enter "<<i+1<<" string"<<endl;
getline(cin,name[i]);
}
int failed = 0;
for(int i = 0;i<4;i++)
{
for(int j=0;j<i;j++)
{
// Check if the string is the same as any previous strings.
if (name[i].compare(name[j]) != 0)
{
failed = 1;
cout<<"String exists multiple times: "<<name[i];
}
}
}
// Check if there were any shared strings
if(failed==0)
{
for(int i=0; i<4; i++)
{
cout<<name[i]<< " ";
}
}
Reference:
http://www.cplusplus.com/reference/string/string/compare/
So the best way is going to be to use a better container!
Lets have a look at a std::set here.
std::set is an associative container that contains a sorted set of
unique objects.
So how can we best use this, there are many examples, but we can look at your particular one.
#include <set> // For Set
int main() {
set<string> names; // our fun easy ordered set.
string name; // a name to read in
unsigned int nameCounter = 0; // a counter
// loop until we have 4 correct names.
while (nameCounter < 4) {
cout<<"Enter "<<nameCounter+1<<" name"<<endl;
getline(cin,name);
// Check that when they enter it into the set that it is actually inserted.
// Here we are being clever because "insert" returns a tuple with a bool
// to tell us if we put it in correctly.
if (!names.insert(name).second) {
cout << "That was not unique!" << endl;
} else {
nameCounter++;
}
}
// Now we can loop through the names which is already sorted for us!
for (auto listName : names) {
cout << listName << " ";
}
cout << endl;
}
Wasn't that easy!? It is almost always better to utilize the std library than do things your self!
Here is a live example.
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if((name[i]==name[j]) && (i!=j)){
cout<<"already exits";
}

For-loop with strings not working

Here is the instructions:
Write a program that reads in a text file one word at a time. Store a word into a dynamically created array when it is first encountered. Create a paralle integer array to hold a count of the number of times that each particular word appears in the text file. If the word appears in the text file multiple times, do not add it into your dynamic array, but make sure to increment the corresponding word frequency counter in the parallel integer array. Remove any trailing punctuation from all words before doing any comparisons.
Create and use the following text file containing a quote from Bill Cosby to test your program.
I don't know the key to success, but the key to failure is trying to please everybody.
At the end of your program, generate a report that prints the contents of your two arrays
Here is my Code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
using namespace std;
int main()
{
ifstream inputFile;
int numWords;
string filename;
string *readInArray = 0;
char testArray[300] = {0};
char *realArray = 0;
const char *s1 = 0;
string word;
int j =1;
int k = 0;
int start =0;
int ending = 0;
char wordHolder[20] = {0};
cout << "Enter the number of words the file contains: ";
cin >> numWords;
readInArray = new string[(2*numWords)-1];
cout << "Enter the filename you wish to read in: ";
cin >> filename;
inputFile.open(filename.c_str());
if (inputFile)
{
cout << "\nHere is the text from the file:\n\n";
for (int i=0; i <= ((2*numWords) -1); i +=2)
{
inputFile >> readInArray[i]; // Store word from file to string array
cout << readInArray[i];
strcat(testArray, readInArray[i].c_str()); // Copy c-string conversion of word
// just read in to c-string
readInArray[j] = " ";
cout << readInArray[j];
strcat(testArray, readInArray[j].c_str()); // This part is for adding spaces in arrays
++j;
}
inputFile.close();
}
else
{
cout << "Could not open file, ending program";
return 0;
}
realArray = new char[strlen(testArray)];
cout << "\n\n";
for(int i=0; i < strlen(testArray); ++i)
{
if (isalpha(testArray[i]) || isspace(testArray[i])) // Is makes another char array equal to
{ // the first one but without any
realArray[k]=testArray[i]; // Punctuation
cout << realArray[k] ;
k++;
}
}
cout << "\n\n";
for (int i=0; i < ((2*numWords) -1); i+=2)
{
while (isalpha(realArray[ending])) // Finds space in char array to stop
{
++ending;
}
cout << "ending: " << ending << " ";
for ( ; start < ending; ++start) // saves the array up to stopping point
{ // into a holder c-string
wordHolder[start] = realArray[start];
}
cout << "start: " << start << " ";
readInArray[i] = string(wordHolder); // Converts holder c-string to string and
cout << readInArray[i] << endl; // assigns to element in original string array
start = ending; // Starts reading where left off
++ending; // Increments ending counter
}
return 0;
}
Output:
Enter the number of words the file contains: 17
Enter the filename you wish to read in: D:/Documents/input.txt
Here is the text from the file:
I don't know the key to sucess, but the key to failure is trying to please everybody.
I dont know the key to sucess but the key to failure is trying to please everybody
ending: 1 start: 1 I
ending: 6 start: 6 I dont
ending: 11 start: 11 I dont know
ending: 15 start: 15 I dont know the
ending: 19 start: 19 I dont know the key
ending: 22 start: 22 I dont know the key to>
ending: 29 start: 29 I dont know the key to sucess
ending: 33 start: 33 I dont know the key to sucess but↕>
My Question:
Something is wrong with the last for-loop, it crashes after I run it. I included the ending and starting variables to maybe help see whats going on. I know there are better ways of doing this problem but the instructor wants it done this way. If you know where I went wrong with the last for-loop any help would be very much appreciated!!
You aren't null-terminating your strings as you go along. You copy the characters correctly, but without null terminators, your loops might go off into the weeds.

Store a word into a dynamically created array when first encountered

Here is the assignment:
Write a program that reads in a text file one word at a time. Store a word into a dynamically created array when it is first encountered. Create a paralle integer array to hold a count of the number of times that each particular word appears in the text file. If the word appears in the text file multiple times, do not add it into your dynamic array, but make sure to increment the corresponding word frequency counter in the parallel integer array. Remove any trailing punctuation from all words before doing any comparisons.
Create and use the following text file containing a quote from Bill Cosby to test your program.
I don't know the key to success, but the key to failure is trying to please everybody.
At the end of your program, generate a report that prints the contents of your two arrays in a format similar to the following:
Word Frequency Analysis
I 1
don't 1
know 1
the 2
key 2
...
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int readInFile (string tempArray [], string file, int arraySize);
int main()
{
ifstream inputFile;
string *readInArray = 0,
*compareArray = 0,
filename,
word;
int wordCount = 0;
int encountered = 0;
int j = 0,
*wordFrequency = 0;
cout << "Enter the filename you wish to read in: ";
getline(cin, filename);
inputFile.open(filename.c_str());
if (inputFile)
{
while (inputFile >> word)
{
wordCount++;
}
inputFile.close();
readInArray = new string[wordCount];
readInFile(readInArray, filename, wordCount);
}
else
{
cout << "Could not open file, ending program";
return 0;
}
compareArray = new string[wordCount];
wordFrequency = new int[wordCount];
for (int count = 0; count < wordCount; count++)
wordFrequency[count] = 0;
for(int i = 0; i < wordCount; ++i)
{
j = 0;
encountered = 0;
do
{
if (readInArray[i] == compareArray[j])
encountered = 1;
++j;
} while (j < wordCount);
if (encountered == 0)
{
compareArray[i]=readInArray[i];
wordFrequency[i] += 1;
}
}
for(int k=0; k < wordCount; ++k)
{
cout << "\n" << compareArray[k] << " ";
}
for(int l=0; l < wordCount; ++l)
{
cout << "\n" << wordFrequency[l] << " ";
}
return 0;
}
int readInFile (string tempArray [], string file, int arraySize)
{
ifstream inputFile;
inputFile.open(file.c_str());
if (inputFile)
{
cout << "\nHere is the text file:\n\n";
for(int i=0; i < arraySize; ++i)
{
inputFile >> tempArray[i];
cout << tempArray[i] << " ";
}
inputFile.close();
}
}
Here is my question:
How do you store a word into a dynamically created array when it is first encountered? As you can see from my code made a string array with some of the elements empty. I believe it is suppose to be done using pointers.
Also how do I get rid of the punctuation in the string array? Should it be converted to a c-string first? But then how would I compare the words without converting back to a string array?
Here is a link to a java program that does something similar:
http://math.hws.edu/eck/cs124/javanotes3/c10/ex-10-1-answer.html
Thank you for any help you can offer!!
As to the first part of your question, you are not using a dynamically created array. You are using a regular array. C++ provides implementations of dymnamic arrays, like the vector class http://www.cplusplus.com/reference/vector/vector/
As to the second part of your question, I see no reason to convert it to a c string. The string class in c++ provides functionality for removing and searching for characters. http://www.cplusplus.com/reference/string/string/
The string::erase function can be used to erase punctuation characters found with string::find.
Note: There are other ways of doing this assignment that may be easier (like having an array of structs containing a string and an int, or using a map) but that may defeat the purpose of the assignment.

How to Output One Word per Line from a String

I've been working on a program my professor gave us awhile back and I've run into a logic issue, as in I can't figure out how to exactly do this. I need to output one word on each line of a sentence input by the user. For example, the user inputs "Hello World I'm Chris" and the program needs to output:
Hello
World
I'm
Chris
This is what I have so far:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence;
int length;
cout << "Enter the sentence now." << endl;
getline(cin, sentence);
for(int i = 0; i < sentence.length(); i++)
{
if(sentence[i] != '\0')
{
cout << sentence[i];
}
else if(sentence[i] == '\0')
{
cout << endl;
}
}
system("pause");
}
However, when I run it, the program basically just outputs the same sentence. Is there another way I can do this? Many thanks.
According to this the \0 does not represent a whitespace. It seems you want something more like:
[...]
if(sentence[i] == ' ') cout << endl; // check for whitespace
else cout << sentence[i];
[...]
By the way, due to the way markdown formats text, the 'one word per line' thing was not clear, I had to fake-edit your post to see what exactly you meant. I think using a code tag would solve that.
Ok first of all with the code feel free to add in the input stuff you have in before!
#include <iostream>
#include <string>
using namespace std;
int main()
{
string sentence = "Hello World";
int length;
string temp = "";
for(int i = 0; i < sentence.length(); i++)
{
temp += sentence[i];
if(sentence[i] == ' ')
{
cout << temp << "\n";
temp = "";
}
}
std::cout << temp;
return 0; //*
}
Your orignal code does the following logic. If it not the end of the file output the current character. Which it does so make sure you add in \n to the end of every word (Just to make debugging easier for you! You can always fix that later)
The logic of the above code does this. Create a temp variable that we will just keep adding letters to until we find a space character. When we find a space character output the temp variable. And reset it do this until the end of the sentence then at the end of the program output temp again since we hit the end of line character!
Your program outputs the same sentence because you told it to.
for(int i = 0; i < sentence.length(); i++)
{
if(sentence[i] != '\0') // If the current char is not the end,
{
cout << sentence[i]; // print the character.
}
else if(sentence[i] = '\0') // This should be "=="
{
cout << endl;
}
}
Basically, you are printing each letter in the sentence back to std::cout.
Please search StackOverflow for "C++ print word sentence", as many people have posted questions about this assignment.
Edit 1: The fundamentals of the assignment
The assignment requires you to extract letters from the input string to form a word. There are many ways to do this. Search your text book or reference manual for the std::basic_string class and see what functions could help you.
Some people start from the first letter in the sentence and search for the next character that is not a letter:
const char valid_letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
sentence.find_first_not_of(valid_letters);
And they use the returned position to get a substring (std::string::substr) between the two positions.
Another approach is to use a loop. If the present character is a letter, append to the word string.
Again search and see what examples you can find.

huffman decoding is going nutts

The problem is that I can decode a data stream for the first time, but then it will become an infinite loop and display the same value over and over again... I'm using borland C++. Decoding is done by first saving the text a to z in an array, then taking the input data stream and then cutting the contents of the array using strcpy then comparing with the contents of the first array then if a match is found, the corresponding ASCII is printed.
code:
#include<conio.h>
#include<iostream.h>
#include<string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int codes[512];
char cut_stream[100];
char input_stream[100];
char decoded_stream[256];
int test,count,cut_start,cut_end,length_of_stream,final,temp_loop_s,temp_loop_e,temp_num,comp_num,send;
void select_num(int select)
{
int output;
output = select + 64;
cout << char(output);
}
void decode()
{
cout<<"\nEnter the data stream ";//<<endl;
cin >> input_stream;
length_of_stream = strlen(input_stream);
//cout<< length_of_stream ; //only for debugging
/********************************************
the code starts here...
********************************************/
count = length_of_stream;
//count -= count;
for(int ini =0; ini<=count ; ini++)
{
for( final=1;final<=count;final++)
{
strncpy(cut_stream, &input_stream[ini], final);
//cut_start = cut_start + 1;
/*********************************************
compare
*********************************************/
temp_num = atoi(cut_stream);
for(int z= 1;z<=26;z++)
{
comp_num = codes[z];
if(comp_num == temp_num)
{
send =z;
select_num(send);
test =1;
comp_num =0;
break;
}
}
if( test ==1)
{
test =0;
ini = final-1; // the increment will be given on the next for loop so it is reduced here
//final =0;
//cout<< "im in test";
break;
}
}
}
cout<< "end";
while(1);
}
//cout<< decoded_stream;
//while(1);
void main()
{
cut_start =0;
cut_end = 1;
cout << "Huffman decoder" << endl;
cout << "Enter the codes for a-z" << endl;
for(int i =1;i<=3;i++)
{
cin >> codes[i];
}
decode();
}
There are least two major bugs in the code:
The codes[] array is uninitialized mostly, you only read in three numbers even though you later access the array for indexes up to 26 or so.
The call to strncpy() is broken in the sense that strncpy() does NOT null-terminate a string when it copies the maximum number of characters; that is, when you call strncpy() with final set to 1, strncpy() copies one character and does NOT append the terminating NUL-character, which will then cause atoi() to fail.
Also, if you are using "0" and "1" characters in your huffman coding, this won't work anyway because numbers "01" and "1" will both be interpreted by atoi() as 1 (one) even though they are different codes. If this is really huffman-coding you shouldn't be using atoi() and integers at all, but just binary or character strings.
Huffman decoding is better done by using a tree data structure. look up any standard book on algorithms for reference.