Sorting out duplicates between 2 char arrays [closed] - c++

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 6 years ago.
Improve this question
I'm struggling with an assignment for my class where we have to take input from the user into a char array (word) and take out the duplicates in the word inputted if needed. Comparing the array of the modified array (word) with the alphabet array (abc) to remove the repeated letters from the list. Once the duplicates are removed then just output the modified word followed by the new form of the alphabet into the newAbc array.
For example:
The word HELLO would first become HELO then after comparing to the alphabet the end output from the new array should be HELOABCDFGIJKMNPQRSTUVXYZ.
I'm stuck more on the for loops comparing the new word to the alphabet really.
char word[20], newAbc[40] = { '\0' };
char abc[27] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int i = 0, b = 1, n = 0, leng, dup;
//dup counts up the repeats but is established in the first portion of the program but i've excluded it as it works perfectly.
cout << "Please enter a word: ";
cin >> word;
leng = strlen(word);
b = 0;
n = leng - dup;
i = 0;
for (i = 0; i < n; i++)
{
for (b = 0; b < 27; b++)
{
if (newAbc[i] != abc[b])
{
newAbc[n] = abc[b];
n++;
}
}
}
for (i = 0; i < 27; i++)
cout << newAbc[i];
cout << endl;
return 0;
}
I'd appreciate any kind of insight on my mistakes.

The major problem for crash is that you are changing n inside for loop for iterating in newAbc. And your if condition will be true for at least 25 times so incrementing n by 25(minimum) in each iteration resulting in accessing out of bound memory(SEG-FAULT).
for (i = 0; i < n; i++)
{
for (b = 0; b < 27; b++)
{
if (newAbc[i] != abc[b]) // this condition is not correct
{ // this will be true atleast 25 times
newAbc[n] = abc[b]; // wrong memory access
n++; // here is the problem
}
}
}
Assuming that your duplicate counting works fine, below are the changes required:-
char word[20];
// FIXME: your new array should not contain no duplicate so size can be 27
char newAbc[40] = {'\0'};
// FIXME: simply can be char abc[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char abc[27] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
cout << "Please enter a word: ";
cin >> word;
// dup counts up the repeats but is established in the first portion of
// the program but i've excluded it as it works perfectly.
// Lets say word = "HELLO"; so dup = 1, and newArray, should have "HELO"
memcpy(newAbc, "HELO", 4); // from your excluded part of code
int dup = 1; // from your excluded part of code
int leng = strlen(word); // length of input word
int n = leng - dup; // char remained to be inserted
// iterator for new array(newAbc)
int c = n; // n elements are already there
// Just reversed your loop
for (int b = 0; b < 27; b++)
{
int found = 0;
for (int i = 0; i < n; i++)
{
if (newAbc[i] == abc[b])
{
found = 1;
break;
}
}
if (!found)
{
newAbc[c] = abc[b];
c++;
}
}
for (int i = 0; i < 27; i++)
cout << newAbc[i];
cout << endl;
return 0;

Related

Reading a Text file and Storing data in 2D Array in C++

Basically, I'm reading a file and trying to store the data in a 2D, for the differentiation between rows and columns I use the logic below:
int rows=0,column=0;
char arr[50][50];
while(my_file.eof()==0){
my_file.get(ch);
if(ch=='\n'){
rows++;
}
arr[rows][column]=ch;
column++;
}
for(int j=0;j<rows;j++){
for(int k=0;k<column;k++){
cout<<arr[j][k];}
}
But the when I run It shows the following output: https://i.stack.imgur.com/XzhST.png
And the text file data is:
I am going to school
hi!
Hello
guide me a bit...
Hmm, a 2D char array can indeed be used to store an number of lines, but you should control that you never try to store more than 50 characters for a single line, and that you never try to ouput more characters for a line than what it initially contained.
Here is a minimal fix of your code:
int rows = 0, column = 0;
char arr[50][50] = { {0 } }; // ensure the array is initialized with '\0' chars
for (;;) {
my_file.get(ch);
if (!my_file) break; // eof shall be tested AFTER a read operation
if (ch == '\n') {
rows++;
if (rows == 50) break; // no more than 50 lines
column = 0; // reset column index for next line
}
else if (column < 50) { // no more than 50 columns
arr[rows][column] = ch;
column++;
}
}
for (int j = 0; j < rows; j++) {
for (int k = 0; k < 50; k++) {
if (arr[j][k] == 0) break; // stop on end of line
std::cout << arr[j][k];
}
std::cout << '\n'; // and display the end of line
}
And as you have been said this is rather C-ish... I assume it is only for learning how 2D arrays can work.
As pointed out in comments, you'd be much better off using a std::vectorstd::string to store the strings.
But, this looks like a homework assignment to read then print each byte separately, so let's have a look... I'll add one of the ways this is usually done at the end of this post.
Your output looks like this:
It looks like you are displaying characters beyond the bondary of the strings, or that your strings are not null terminated... Turns out it's both.
Your code:
int rows = 0, column = 0;
char arr[50][50]; // <-- your array is not initialized, while that is not
// a big issue, filling the array with zeroes is easy:
// char arr[50][50] = {};
while (my_file.eof() == 0) {
my_file.get(ch);
if (ch == '\n') {
rows++; // <-- you pass to the next string, but do not put a
// null character to properly terminate your strings
// while this could have been avoided by initializing
// the array, it's best to do it explicitely.
// replace above line contents by:
arr[row][column] = '\0';
if (++row >= 50) // consider using named constants for the size of your array.
break; // No use keeping on reading strings if there is no
// more room to store them
}
arr[rows][column] = ch; // <-- I suspect a bunch un undefined stuff will
// start happening when column >= 50
column++;
// Try replacing above code with:
if (column < 50) // consider using named constants for the size of your array.
arr[rows][column++] = ch;
}
// make sure the last string is null terminated.
if (row < 50 && column < 50)
arr[row][column] = '\0';
// note that strings that are 50 bytes long are NOT null terminated.
// that's important to keep in mind, and only workss because we'll print
// byte by byte.
// your original print routine prints out all characters in the array, even
// stuff that was not in the original file...
for (int j = 0; j < rows; ++j){
for (int k=0 ; k < column; ++k){ // <-- you need to check for a null
// terminating character here...
// also, column is the length of the last
// string in the array. This is not a very
// useful value for displaying any other
// strings, is it?
// try this:
for (int k = 0; k < 50 && arr[j][k] != '\0'; ++k)
cout << arr[j][k];
}
cout << '\n'; // insert a newline after each string.
}
As you can tell, this is overly complex for doing a very common operation... Here's a more concise way of doing the same thing:
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
int main()
{
std::vector<std::string> arr;
std::ifstream ifs("testfile.txt");
while (ifs && !ifs.eof())
{
std::string str;
std::getline(ifs, str);
arr.push_back(str);
}
for (size_t i = 0; i < arr.size(); ++i)
std::cout << arr[i] << '\n';
return 0;
}
Because you haven't compile the array yet
char arr[50][50];
for (int r = 0; r < 50; r++){
for (int c = 0; c < 50; c++){
arr[r][c] = ' ';}
}

C++ delete duplicates from cstring [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 2 years ago.
Improve this question
I have a c-string that looks something like ABBBCACACACBA and I'm supposed to create a function that deletes the duplicate characters so I end up with ABC. I created a nested for loop that replaces every letter that matches the letter in the outer loop with a \0 and increments a counter that keeps track of the repeats. I'm getting -1 as the amount of repeats that should be documented, and from checking it spits out ABBC instead of ABC. I'm stumped, any ideas?
for (int i = 0; i < SIZE; i++)
{
for (int j = i + 1; j < SIZE; j++)
{
if (letter[i] == letter[j])
{
letter[j] = '\0';
repeatCounter++;
}
}
}
It is not enough to just replace duplicates with '\0', you have to actually remove them from the string and shift the remaining characters down. Try something more like this:
int size = SIZE, i = 0;
while (i < size)
{
int j = i + 1;
while (j < size)
{
if (letter[j] == letter[i])
{
for (int k = j + 1; k < size; k++)
{
letter[k-1] = letter[k];
}
letter[--size] = '\0';
repeatCounter++;
continue;
}
j++;
}
i++;
}
Live Demo
Here's a simple example which does what you want. It uses std::string to store the output. You can copy-n-paste the code here to test and run. Look into using std::string as it has functions which will make your life easy.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input("ABBBCACACACBA");
string output;
for(size_t i = 0; i < input.size(); i++)
{
if(output.find(input[i]) == string::npos)
{
output += input[i];
}
}
cout << "Input: " << input << endl;
cout << "Output: " << output << endl;
return 0;
}

Filling up the vector with given input and searching a word on it later

Here, i am editing my question.
while (iter <= k && getline(input, line))
{
searchWord.clear();
int len = line.length();
if (len == 0) // getline function was not getting the third line. It was empty so. at 2-3 lines below. It was giving run time error because it was trying to access a vector's element fileed with empty string(line)
{
cout << count << " Words are Found:" << total_words << endl;
return 0;
}
for (int i = 0; i < len; i++)
{
ch1 = line.at(i);
searchWord.push_back(ch1);
}
for (int col = 1; col <= n; col++)
{
for (int row = 1; row <= n; row++)
{
if (mat[col][row] == searchWord[0]) // aranıalcak kelımenın boyutuna erisılene kadar harf harf matrix in ilk harfi ile aranan kelımenın ılk harfı sonra 2. harfı uyuyot mu dıye bakılacak bu loop un ıcıne spiral gitme algoritması yazılacak.
{
if (found(mat, searchWord, row, col)) // spiral arama loop u
{
count++;
for (int i = 0; i < searchWord.size(); i++) // if word is found add it to total words and afterwards leave a space.
{
total_words += searchWord[i];
}
total_words += " ";
}
}
}
}
row = 1;
iter++;
}
this code does not work for 3rd time .For example lets say this is our file contains these words seperated with only enter
EXAM
QUIZ
NOTFOUND
it gets exam and quiz perfectly and does eerything right. But it does not gets "NOTFOUND" in line at 3rd iteration of loop. So it does not enter the for loop at beginning and it crashes when it tries to reach outside of the searchWord vector.
What could be done ?
Firstly, I think this might be helpful to your problem
Secondly, in this line
mat[row][col] == ch;
you are comparing an element of matrix with ch
What you really just need to do:
mat[row][col] = ch;
It's a common mistake, so don't forget that comparison operator == is used only when you need to get a bool, and assignment operator = is, well, assignment to some variable.

How is this line returning the length of the array in recursion?

I am trying to understand this recursion using the debugger and trying to understand it step by step the main.The debugger shows the smallAns returns the size of the array I can't understand how this smallAns is returning the size of the array input[].can anyone explain this
#include<iostream>
using namespace std;
int subsequences(char input[], int startIndex,char output[][50]){
if(input[startIndex] == '\0'){
output[0][0] = '\0';
return 1;
}
int smallAns = subsequences(input, startIndex+1, output);
for(int i = smallAns; i < 2*smallAns; i++){
int row = i - smallAns;
output[i][0] = input[startIndex];
int j = 0;
for(; output[row][j] != '\0'; j++){
output[i][j + 1] = output[row][j];
}
output[i][j + 1] = '\0';
}
return 2*smallAns;
}
int main(){
char input[] = "abc";
char output[100][50];
int ans = subsequences(input, 0, output);
for(int i = 0; i < ans; i++){
for(int j = 0; output[i][j] != '\0'; j++){
cout << output[i][j];
}
cout << endl;
}
}
Here's what the algorithm is doing:
Start at the end, with the empty subsequence (or "\0"). You have 1 subsequence.
Look at the last character not yet considered. For all the subsequences you have found, you can either add this last character, or don't. Therefore you have doubled the number of subsequences.
Repeat.
Therefore, 2 * smallAns means "Take the number of subsequences found in the lower recursive call, and double it." And this makes sense after you know how it was implemented. Thus the importance of comments and documentation in code. :)

Working with vectors C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Complicated question, probably simple answer. So the program I need to make cannot include any library other than String, iostream, and vector. I need to create a program that has 3 functions. One that creates an integer vector, one that reverses a vector, and one that prints a vector. In order to take in values I need to use getline to intake a string, if the string states quit, we stop putting new values into it. Other wise we need to test if its an integer(positive or negative) and add it to the vector. My code is starting to get complicated so I really need some help. Below is what i have so far. I'm also using Visual Studio, if that matters. Thanks for any help in advance! The question I have is when I run the program, it will only output the first digit. I don't know why and would like to know what I'm doing wrong.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<int> CreateVector()
{
string tempvariable;
bool quit = false;
vector<int> userinput;
cout << "Please enter in an integer, type 'quit' to exit " << endl;
while (!quit)
{
getline(cin, tempvariable);
if (tempvariable == "quit")
quit = true;
else
{
bool isaninteger = true;
for(int i = 1; i <= tempvariable.size(); i++)
{
if (tempvariable[i] = "-" || isdigit(tempvariable[i]))
continue;
else
{
cout << "You entered in an incorrect option, please enter in a correct option" << endl;
cin.clear();
cin.ignore();
isaninteger = false;
break;
}
}
if (isaninteger)
userinput.push_back(stoi(tempvariable));
cout << "Please enter in an integer, type 'quit' to exit " << endl;
}
}
return userinput;
}
void printVector(vector<int> userinput)
{
int amountofspots = userinput.size();
cout << "Your Vector is ";
for (int i = 0; i < amountofspots; i++)
{
if (i = (amountofspots - 1))
cout << userinput.at(i) << endl;
else
cout << userinput.at(i) << " , ";
}
}
void reverseVector(vector<int>& userinput)
{
int amountofspots = userinput.size();
vector<int> tempvector;
for (int i = 0; i < amountofspots; i++)
tempvector.push_back(userinput.at(amountofspots - i));
for (int i = 0; i < amountofspots; i++)
userinput.pop_back();
for (int i = 0; i < amountofspots; i++)
userinput.push_back(tempvector.at(i));
}
int main()
{
vector<int> CreatedVector = CreateVector();
printVector(CreatedVector);
reverseVector(CreatedVector);
printVector(CreatedVector);
system("pause");
return 0;
}
Change if (i = (amountofspots - 1)) to if (i == (amountofspots - 1)) in the loop in printVector().
Change tempvariable[i] = "-" to tempvariable[i] == '-' in CreateVector().
= is the assignment operator, == is the comparison operator. Also, single characters are surrounded by single quotes, not double quotes.
void reverseVector(vector<int>& userinput)
{
int amountofspots = userinput.size();
vector<int> tempvector;
for (int i = 0; i < amountofspots; i++)
tempvector.push_back(userinput.at(amountofspots - i));
should probably be
void reverseVector(vector<int>& userinput)
{
int amountofspots = userinput.size();
vector<int> tempvector;
for (int i = 1; i < amountofspots+1; i++) // Index error
tempvector.push_back(userinput.at(amountofspots - i));
The following:
for(int i = 1; i <= tempvariable.size(); i++)
{
if (tempvariable[i] = "-" || isdigit(tempvariable[i]))
Must become:
for(int i = 0; i < tempvariable.size(); i++)
{
if (tempvariable[i] == '-' || isdigit(tempvariable[i]))
Explanation:
String indices start from 0 and end at size() - 1.
[i] returns a single char. "-" is not a single char but an entire string literal. You cannot directly compare a single char with an entire string. -, however, is a single char, so that comparison will work.
= is not comparison but assignment. == is used for comparison. As your compiler should have warned you!
Note that there are further problems with your code:
if (i = (amountofspots - 1))
You are again mixing assignment and comparison. Make that ==. And pay attention to compiler warnings!
And finally, isdigit is not exactly a great function. In order to really use it correctly, you'd first have to cast the operand to int and at the same time make sure it is not an invalid value, as documented here.
Why don't you just catch the exception thrown by stoi if the specified string cannot be parsed?