BinSearch fails after Bubble Sort - c++

My program seems to be behaving oddly all of a sudden and I cannot figure out why no matter how I look.
Let's begin with the header
//inventoryData.h
//This is the second edition of inventory data, now featuring an actual description
//This header will load an array, sort it, and then be used in InventorySearch to produce parts and prices.
//by Robert Moore on [DATE]
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
class InventoryData{
//Variables
private:
int partNum[1000];
double price[1000];
int invCount;
public:
InventoryData();//Build Up
void loadArrays(); //Feed the data from the database into our arrays
void arraySort(); //Bubblesort for the array
int seqSearch(int); //Our one by one search method
int binSearch(int); //The other search
int returnpart(int); //Return Part Number
double returnPrice(int); //Return price
//Incorportate a search counter to both these searches?
//IE: bin search found [x] (completed after [y] records)
};
InventoryData::InventoryData()
{
//Load the array
invCount = 0;
for (int count = 0; count < 1000; count++)
{
partNum[count] = 0;
price[count] = 0;
}
}
void InventoryData::arraySort()
{
int counter = 0; //Used to keep track of subscripts
int temp = 0; //Used to sort subscript contents
double tempPrice = 0;
int maxSub = invCount;
int lastKnown = 0; //Used to indicate what the last swapped value was
char swap = 'Y'; //used to indicate if a swap was made or not
while (swap == 'Y')
{
swap = 'N';
counter = 0;
while (counter < maxSub){
if (partNum[counter] < partNum[counter+1])
{
//Swap the part number
temp = partNum[counter];
partNum[counter] = partNum[counter+1];
partNum[counter+1] = temp;
//Swap the price
tempPrice = price[counter];
price[counter] = price[counter+1];
price[counter+1] = tempPrice;
//Report the swap occured
swap = 'Y';
lastKnown = counter;
}
counter++;
}//End of While Loop
maxSub = lastKnown;
}//End this While Loop Too
cout<<"File sort complete."<<endl;
}
void InventoryData::loadArrays()
{
ifstream partIn;
partIn.open("masterInventory.dat");
cout<<"Loading..."<<endl;
if (partIn.is_open())
{
//Prime Read
partIn >> partNum[invCount]
>> price[invCount];
//cout<<partNum[invCount]<<" and "<<price[invCount] <<" have been loaded."<<endl;
while(!partIn.eof())
{
invCount++;
partIn >> partNum[invCount]
>> price[invCount];
// cout<<partNum[invCount]<<" and "<<price[invCount] <<" have been loaded."<<endl;
} //END While
partIn.close();
cout<<"All files loaded successfully."<<endl;
} //END IF*/
else
{
invCount = -1;
cout<<"File failed to open."<<endl;
}
//arraySort();
}
int InventoryData::seqSearch(int searchKey)
{
int index = 0;
int found = -1;
int counter = 0;
while(index < invCount)
{
counter++;
if (searchKey == partNum[index]
)
{
found = index;
index = invCount;
}
else
{
index++;
}
}
cout<<"(Sequential completed after reading "<< counter<<" files.)"<<endl;
return found;
}
int InventoryData::binSearch(int searchKey)
{
int first = 0;
int last = invCount;
int found = 0;
int mid = 0;
int counter = 0;
while (first <= last && found == 0)
{
counter++;
mid = (first + last)/2;
if (searchKey == partNum[mid] ){
found = 1;
return mid;
}
else
{
if (partNum[mid] < searchKey)
{
first = mid+1;
}
else
{
last = mid - 1;
}
}
}
if (found == 0)
{
mid = -1;
}
cout<<"(Binary completed after reading "<< counter <<" files.)"<<endl;
return mid;
}
int InventoryData::returnpart(int value)
{
return partNum[value];
}
double InventoryData::returnPrice(int value)
{
setprecision(2);
return price[value];
}
With this set up, the program loads numbers from a database (any random combination of digits and another set of "prices"), then we call the function to load, sort, and search the array, as found in the CPP file
//InventorySearch
/*This file is used to search our databases
and return a value for whatever our search may
be looking for.*/
//by Robert Moore
#include "inventoryData.h"
#include <iomanip>
int main()
{
//Declare Variable
int tempSeq = 0;
int tempBin = 0;
int search = 0;
char confirmation = 'Y';
int searchCounter = 0;
int partsFound = 0;
int partsLost = 0;
//Build Object and Load Array
InventoryData invent;
invent.loadArrays();
invent.arraySort();
//Introduction
cout<<"Welcome to Part Search."<<endl;
//Begin Loop Here
while(confirmation != 'N')
{
cout<<"Please enter a part number: ";
searchCounter++;
cin>>search;
cout<<endl;
tempSeq = invent.seqSearch(search);
if (tempSeq != -1)
{
std::cout << std::fixed;
cout<<"Sequential found part number "<<invent.returnpart(tempSeq)<< ", and it's price is "<<setprecision(2)<<invent.returnPrice(tempSeq)<<endl;
partsFound++;
}
else
{
cout<<"Sequential search failed to find part number "<<search<<endl;
partsLost++;
}
tempBin = invent.binSearch(search);
if (tempBin != -1)
{
std::cout << std::fixed;
cout<<"Binary found part number "<<invent.returnpart(tempBin)<<", and it's price is "<<setprecision(2)<<invent.returnPrice(tempBin)<<endl;
partsFound++;
}
else
{
cout<<"Binary search failed to find part number "<<search<<endl;
partsLost++;
}
cout<<"Would you like to search again? (Plese enter Y/N): ";
cin>>confirmation;
confirmation = toupper(confirmation);
}
cout<<"Today's Summary: "<<endl;
cout<<setw(5)<<"Total searches: "<<setw(25)<<searchCounter<<endl;
cout<<setw(5)<<"Total successful searches:"<<setw(15)<<(partsFound/2)<<endl;
cout<<setw(5)<<"Total unsuccessful searches:"<<setw(12)<<(partsLost/2)<<endl;
cout<<"Thank you for using Part Search. Have a nice day."<<endl;
return 0;
}
However, the output runs into the following problem: where the sequential search will scour the entire database and find our value, the binSearch will only search up to 8 values and fail. At first I thought this was due to the way the sort was loaded, but once I coded it out, it continued to fail. Worse yet, aside from adding the sort, the program function just fine prior to this.
I'm running out of ideas as to where the program is wrong, as this code worked just fine up until arraySort() was added.

In your arraySort() method, you should take note of the fact that for instance if maxSub=10, then for the part where you write
while (counter < maxSub){
if (partNum[counter] < partNum[counter+1])
{
.....
}
}
you might end up performing
if(partNum[9]<partNum[10]){
....
}
Since C++ does not perform bound checking on arrays, your code, although buggy, might end up compiling successfully, and may (or may not) produce the correct result. Thus you need to change the loop condition to
while((counter+1)<maxSub){
.....
}
Besides, your arraySort() is sorting in the Descending order, and your binSearch() has been implemented for an array sorted in ascending order. You can change either of the methods as per your requirement.
Hope this helps.

Your sorting algorithm seems faulty to me. If you are trying bubble sort, sorting implementation should be like this.
for(int counter1 = 0;counter1<invCount; ++counter1)
{
for(int counter2 = counter1+1; counter2<invCount; ++counter2)
{
if(partNum[counter1] < partNum[counter2])
{
//do swaping here.
}
}
}

Related

Trying to make a program that automatically sorts an array before using binary searching

I'm trying to make a program that asks the user to input a set of 10 numbers before asking them to select a number from the list. it would first automatically sort the ten numbers before being placed in a binary searching function.
Here's the code I wrote.
#include <iostream>
using namespace std;
int searchbinary(int arr[], int left, int right, int x){
while (left <= right){
int mid = left+(right-left)/2;
if (arr[mid]==x){
return mid;
}
else if (arr[mid]<1){
left = mid + 1;
}
else{
right = mid -1;
}
}
return -1;
}
int main(){
int num;
int darr[10];
int output;
int temp;
cout << "Enter 10 Numbers: " << endl;
for (int i=0; i<10; i++){
cin >> darr[i];
}
for (int i=0;i<10;i++){
for (int j=i+1;j<10;j++){
if (darr[i]>darr[j]){
temp = darr[i];
darr[i] = darr[j];
darr[j] = temp;
}
}
}
cout << "Enter a number from list: ";
cin >> num;
output = searchbinary(darr, 0, 9, num);
if (output ==-1){
cout << "Match not Found";
}
else {
cout << "Match Found in Position " << output;
}
return 0;
}
It works fine when I do it separately, but combining the two seems to cause an issue. Any suggestions?
Well, there seems to be a problem with your Binary Search. In the else if condition you wrote arr[mid] < 1 whereas it should have been arr[mid] < x because you are trying to find x not 1. Bellow is the code that should work:
#include <iostream>
using namespace std;
//binary search
int searchbinary(int arr[], int left, int right, int x){
while (left <= right){
int mid = (right+left)/2;//this formula is better than the one you used, it has the same results though
if (arr[mid] == x){
return mid;
}
else if (arr[mid] < x) {//here was your mistake,it is x not 1
left = mid + 1;
}
else{
right = mid -1;
}
}
return -1;
}
int main(){
int num;
int darr[10];
int output;
int temp;
cout << "Enter 10 Numbers: " << endl;
//input
for (int i=0; i<10; i++){
cin >> darr[i];
}
//sorting
for (int i=0;i<10;i++) {
for (int j=i+1;j<10;j++) {
if (darr[i]>darr[j]) {
temp = darr[i];
darr[i] = darr[j];
darr[j] = temp;
}
}
}
cout << "Enter a number from list: ";
cin >> num;
output = searchbinary(darr, 0, 9, num);//searching
//output
if (output == -1){
cout << "Match not Found";
}
else {
cout << "Match Found in Position " << output;
}
return 0;
}
If you fix that issue then your code should work but I would like to point some things out:
It is better not to hardcode numbers, like when you write 10 as a limit to all for loops. It would be better to save 10 in a variable or use darr.length().
Instead of using your own Sort you could have used the built-in sort that the algorithm library provides like this sort(darr, darr+10). In this case it was only with 10 elements but bear in mind that if you ever find yourself trying to solve the same problem with array sizes up to a million or more, the sort you implemented(it is called Bubble sort), would take up to much time, whereas std::sort would be able to do it faster as it has been optimised.
In this problem first sorting the array and then using Binary Search on top of it takes more time than performing Linear Search on the unsorted array. Generally, when searching once for a value on an unsorted array, first sorting it and then using Binary Search takes up more time than just doing Linear Search no matter the size of the array. However, if you wanted to to use the array in the future multiple times then your approach could prove to be faster.
These are all small improvements that you could make to your code but I am guessing this is done for educational purposes that is why you didn't do some of them.

Finding most common k-mers and their number of apperance in C++

Regarding kmer https://en.wikipedia.org/wiki/K-mer
I am trying to find most frequent k-mers in a large fastq file. My plan was to use misra-gries algorithm to find most frequent k-mers, then searching each frequent k-mer's count in file with a second pass. Yet I don't think my algorithm is efficient enough. Here is my first draft below. I try to be memory efficient as possible.(program must not run out of memory)
I also found this DSK algorithm, yet this one is too hard for me to understand without seeing a simple implementation. http://minia.genouest.org/dsk/
Note: Also ID of each counter will be integers not strings, I am going to change it later in my final draft.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
struct node {
string id;
int count;
};
void searchCount(vector <node>&memory, string line,int k) {
int count = 0;
string kMer;
for (int i = 0; i < memory.size(); i++) {
if (memory[i].id != "") {
for (int j = 0; j < line.length() - k + 1; j++) {
kMer = line.substr(j, k);
if (kMer == memory[i].id) {
count++;
}
}
}
memory[i].count = count;
count = 0;
}
}
int doWeHaveSpace(vector <node> memory) {
for (int i = 0; i < memory.size(); i++) {
if (memory[i].id == "") {
return i;
}
}
return -1;
}
void MisraGries(string element, vector <node> &memory) {
bool isHere = false;
int index;
for (int i = 0; i < memory.size(); i++) {
if (memory[i].id == element) {
isHere = true;
index = i;
}
}
if (isHere) {
memory[index].count++;
}
else {
int freeIndex = doWeHaveSpace(memory);
if (freeIndex+1) {
memory[freeIndex].count++;
memory[freeIndex].id = element;
}
else {
for (int i = 0; i < memory.size(); i++) {
if (memory[i].count != 0) {
memory[i].count--;
if (memory[i].count == 0) {
memory[i].id = "";
}
}
}
}
}
}
void filecheck(ifstream & input, string prompt) // this function checks and opens input files
{
string filename;
cout << "Please enter file directory and name for " << prompt << ": ";
do
{
getline(cin, filename);
input.open(filename.c_str());
if (input.fail())
cout << " wrong file directory. Please enter real directory. ";
} while (input.fail());
}
int main() {
int line = 1;
string filename;
ifstream input;
ofstream output;
string search;
vector <node> frequent(1000);
for (int i = 0; i < frequent.size(); i++) {
frequent[i].id = "";
frequent[i].count = 0;
}
int k = 30;
string kMer;
filecheck(input, "input file");
while (!input.eof())
{
getline(input, search); // it gets infos line by line to count lines
line++;
if (line == 3) {
for (int i = 0; i < search.length() - k + 1; i++) {
kMer = search.substr(i, k);
MisraGries(kMer, frequent);
}
line = -1;
}
}
return 0;
}
You can speed up your code by storing the most frequent k-mers in a hash table instead of an array. This way, you'll be able to process one k-mer in O(1) time (assuming that the length is constant) if it's already in the cache (if it's not, it would still require a linear pass, but it might give a big improvement on average).
You could also make it even faster if there're a lot of misses by keeping additional information in some kind of auxiliary data structure (like a priority queue) so that you can find the element with count = 0 and remove them without checking all other elements.
Taking into account that k is pretty small in your example, you could increase the size of your in-memory cache (a typical computer should easily keep a few millions of such strings in memory) so that there're less misses.
You could store even more data during the first pass by hashing k-mers (this way, you'll just need to store integers in memory instead of strings).
To sum it up, I'll recommend to make the cache larger (as long as it fits into memory) and use a more suitable data structure that supports fast lookups, like a hash table (std::unordered_map in C++).

Equal elements in an unsorted array

I am making a program to identify whether a 5 card ( user input ) array is a certain hand value. Pair, two pair, three of a kind, straight, full house, four of a kind ( all card values are ranked 2-9, no face cards, no suit ). I am trying to do this without sorting the array. I am currently using this to look through the array and identify if two elements are equal to each other
bool pair(const int array[])
{
for (int i = 0; i < array; i++)
{
if (array[i]==aray[i+1])
{
return true;
}
else
return false;
}
Does this section of code only evaluate whether the first two elements are the same, or will it return true if any two elements are the same? I.E if the hand entered were 2,3,2,4,5 would this return false, where 2,2,3,4,5 would return true? If so, how do I see if any two elements are equal, regardless of order, without sorting the array?
edit: please forgive the typos, I'm leaving the original post intact, so as not to create confusion.
I was not trying to compile the code, for the record.
It will do neither:
i < array will not work, array is an array not an int. You need something like int arraySize as a second argument to the function.
Even if you fix that then this; array[i]==aray[i+1] will cause undefined behaviour because you will access 1 past the end of the array. Use the for loop condition i < arraySize - 1.
If you fix both of those things then what you are checking is if 2 consecutive cards are equal which will only work if the array is sorted.
If you really cant sort the array (which would be so easy with std::sort) then you can do this:
const int NumCards = 9; // If this is a constant, this definition should occur somewhere.
bool hasPair(const int array[], const int arraySize) {
int possibleCards[NumCards] = {0}; // Initialize an array to represent the cards. Set
// the array elements to 0.
// Iterate over all of the cards in your hand.
for (int i = 0; i < arraySize; i++) {
int myCurrentCard = array[i]; // Get the current card number.
// Increment it in the array.
possibleCards[myCurrentCard] = possibleCards[myCurrentCard] + 1;
// Or the equivalent to the above in a single line.
possibleCards[array[i]]++; // Increment the card so that you
// count how many of each card is in your hand.
}
for (int i = 0; i < NumCards; ++i) {
// If you want to check for a pair or above.
if (possibleCards[i] >= 2) { return true; }
// If you want to check for exactly a pair.
if (possibleCards[i] == 2) { return true; }
}
return false;
}
This algorithm is actually called the Bucket Sort and is really still sorting the array, its just not doing it in place.
do you know the meaning of return keyword? return means reaching the end of function, so in your code if two adjacent values are equal it immediately exits the function; if you want to continue checking for other equality possibilities then don't use return but you can store indexes of equal values in an array
#include <iostream>
using namespace std;
int* CheckForPairs(int[], int, int&);
int main()
{
int array[ ]= {2, 5, 5, 7, 7};
int nPairsFound = 0;
int* ptrPairs = CheckForPairs(array, 5, nPairsFound);
for(int i(0); i < nPairsFound; i++)
{
cout << ptrPairs[i] << endl;
}
if(ptrPairs)
{
delete[] ptrPairs;
ptrPairs = NULL;
}
return 0;
}
int* CheckForPairs(int array[] , int size, int& nPairsFound)
{
int *temp = NULL;
nPairsFound = 0;
int j = 0;
for(int i(0); i < size; i++)
{
if(array[i] == array[i + 1])
nPairsFound++;
}
temp = new int[nPairsFound];
for(int i(0); i < size; i++)
{
if(array[i] == array[i + 1])
{
temp[j] = i;
j++;
}
}
return temp;
}
You could use a std::unordered_set for a O(n) solution:
#include <unordered_set>
using namespace std;
bool hasMatchingElements(const int array[], int arraySize) {
unordered_set<int> seen;
for (int i = 0; i < arraySize; i++) {
int t = array[i];
if (seen.count(t)) {
return true;
} else {
seen.insert(t);
}
}
return false;
}
for (int i = 0; i < array; i++)
{
if (array[i]==aray[i+1])
{
return true;
}
else
return false;
This loop will only compare two adjacent values so the loop will return false for array[] = {2,3,2,4,5}.
You need a nested for loop:
#include <stdio.h>
#include <stdbool.h>
int main()
{
int unsortedArray[] = {2,3,2,4,5};
int size = 5;
for(int i=0;i<size-1;i++)
{ for(int j=i+1;j<size;j++)
{ if(unsortedArray[i]==unsortedArray[j])
{ printf("matching cards found\n");
return 0;
}
}
}
printf("matching cards not found\n");
return 0;
}
----EDIT------
Like Ben said, I should mention the function above will only find the first instance of 2 matching cards but it can't count how many cards match or if there are different cards matching. You could do something like below to count all the number of matching cards in the unsortedArray and save those values into a separate array. It's messier than the implementation above:
#include <iostream>
#include <stdio.h>
#include <stdbool.h>
#defin NUM_CARDS 52;
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int N,i,j;
cin>>N;
int unsortedArray[N];
for(int i=0;i<N;i++)
cin>>unsortedArray[i];
int count[NUM_CARDS]={0};
int cnt = 0;
for( i=0;i<N-1;i++)
{
for( j=i+1;j<N;j++)
{ if(unsortedArray[i]==-1)
break;
if(unsortedArray[i]==unsortedArray[j])
{
unsortedArray[j]=-1;
cnt++;
}
}
if(unsortedArray[i]!=-1)
{
count[unsortedArray[i]]=cnt; //in case you need to store the number of each cards to
// determine the poker hand.
if(cnt==1)
cout<<" 2 matching cards of "<<unsortedArray[i]<<" was found"<<endl;
else if(cnt>=2)
cout<<" more than 2 matching cards of "<<unsortedArray[i]<<" was found"<<endl;
else
cout<<" no matching cards of "<<unsortedArray[i]<<" was found"<<endl;
cnt = 0;
}
}

How to display duplicate characters in a string in C++?

I am working on some code for a class that requires me to output duplicates in a string. This string can have any ascii character but the output needs to show only the repeated character and the total number of times it repeats.
Here are some sample inputs and outputs
mom, m:2
taco, No duplicates
good job, o:3
tacocat, t:2 c:2 a:2
My code works for all but the last test case, the t:2 and a:2 appears twice, Now I have come to the conclusion that I need to store duplicated characters somewhere and run a check on that list to see if that duplicate has already been printed so I tried using a vector.
My method is to push the character into the vector as the duplicates are printed and if a character is already in the vector then it is skipped in the printing. But I have not been able to find a way to this. I tried to use the find() from #include<algorithm> but got a syntax error that I am unable to fix. Is there a function that I can apply for this? Or am I going about this in a bad way?
I found the implementation of find() here & I looked here but they don't match and it breaks my code completely when I try to apply it.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
vector <char> alreadyprintedcharacters;
void findrepeats(string const&);
int main()
{
string input;
cout << "Enter the input : ";
getline(cin, input);
findrepeats(input);
return 0;
}
void findrepeats(string const &in)
{
int trackerOfDuplicates = 0;
int asciiArray[256];
char ch;
int charconv;
for (int i = 0; i < 256; i++) // creates my refference array for the comparison and sets all the values equal to zero
asciiArray[i] = 0;
for (unsigned int i = 0; i < in.length(); i++)
{
ch = in[i];
charconv = static_cast<int>(ch);
if (asciiArray[charconv] == 0)
{
asciiArray[charconv] = 1;
}
else if (asciiArray[charconv] > 0)
{
asciiArray[charconv] = asciiArray[charconv]++;
}
}
bool trip = false;
for (unsigned int i = 0; i < in.length(); i++)
{
char static alreadyprinted;
char ch = in[i];
if ((asciiArray[ch] > 1) && (ch != alreadyprinted) && (find(alreadyprintedcharacters.begin(), alreadyprintedcharacters.end(), ch)!= alreadyprintedcharacters.end()))// change reflected HERE
{
cout << in[i] << " : " << asciiArray[ch] << endl;//???? maybe a nested loop
trip = true;
alreadyprinted = ch;
alreadyprintedcharacters.push_back(alreadyprinted);
}
}
if (trip == false)
cout << "No repeated characters were found.\n";
}
Your code works fine for me (gives the correct output for tacocat) if you fix the error related to std::find:
std::find doesn't return a bool, it returns an iterator (in your case, a std::vector<char>::iterator). If you want to check if std::find found something, you should compare it to alreadyprintedcharacters.end(), because that's what std::find returns if it didn't find something.
You can create an integer array of 256 and initialize it to 0 at first. Then loop over characters in the string and increment each index that corresponds to that letter. In the end, you can print out letters that have values greater than 1. Just change your findrepeats function to the following:
void findrepeats(string const &in)
{
int asciiArray[256];
char ch;
int charconv;
bool foundAny = false;
for (int i = 0; i < 256; i++) asciiArray[i] = 0;
for (unsigned int i = 0; i < in.length(); i++)
{
ch = in[i];
charconv = static_cast<int>(ch);
asciiArray[charconv]++;
}
for (unsigned int i = 0; i < 256; i++)
{
char static alreadyprinted;
if (asciiArray[i] > 1)
{
foundAny = true;
cout << static_cast<char>(i) << " : " << asciiArray[i] << endl;
}
}
if (!foundAny)
cout << "No repeated characters were found.\n";
}
You have to make following changes in your code
change the loop body where you are updating the reference array for the comparison and sets all the values like this:
//your code
else if (asciiArray[charconv] > 0)
{
asciiArray[charconv] = asciiArray[charconv]++;
}
in the above code the value of asciiArray[charconv] doesn't change because it is a post increment asciiArray[charconv]++; , either change it to a pre increment ++asciiArray[charconv]; or write asciiArray[charconv] = asciiArray[charconv]+1;
Here is a link to this why it doesn't increment.
Also you can change the loop like this,more simplified:
for (unsigned int i = 0; i < in.length(); i++)
{
ch = in[i];
charconv = static_cast<int>(ch);
asciiArray[charconv]++;
}
change the type of found to std::vector<char>::iterator coz find returns an iterator to the first element in the range that compares equal to val & if no elements match, the function returns last.
std::vector<char>::iterator found = find(alreadyprintedcharacters.begin(), alreadyprintedcharacters.end(), ch);
Then your condition should be like
if((asciiArray[ch] > 1) && (ch!=alreadyprinted) && (found == alreadyprintedcharacters.end()))
I don't quite get why you need all of that code (given you stated you can't use std::map).
You declared an array of 256 and set each item to 0, which is OK:
for (int i = 0; i < 256; i++)
asciiArray[i] = 0;
Now the next step should be simple -- just go through the string, one character at a time, and increment the associated value in your array. You seem to start out this way, then go off on a tangent doing other things:
for (unsigned int i = 0; i < in.length(); i++)
{
ch = in[i]; // ok
asciiArray[ch]++;
We can set a boolean to true if we discover that the character count we just incremented is > 1:
bool dup = false;
for (unsigned int i = 0; i < in.length(); i++)
{
ch = in[i]; // ok
asciiArray[ch]++;
if ( asciiArray[ch] > 1 )
dup = true;
}
That is the entire loop to preprocess the string. Then you need a loop after this to print out the results.
As to printing, just go through your array only if there are duplicates, and you know this by just inspecting the dup value. If the array's value at character i is > 1, you print the information for that character, if not, skip to the next one.
I won't show the code for the last step, since this is homework.
Just met similar question last week, here is what I did, maybe not a best solution, but it did work well.
string str("aer08%&#&%$$gfdslh6FAKSFH");
vector<char> check;
vector<int> counter;
//subscript is the bridge between charcheck and count. counter[sbuscript] store the times that check[subscript] appeared
int subscript = 0;
bool charisincheck = false;
for (const auto cstr : str) //read every char in string
{
subscript = 0;
charisincheck = false;
for (const auto ccheck : check) // read every element in charcheck
{
if (cstr == ccheck)//check if the char get from the string had already existed in charcheck
{
charisincheck = true; //if exist, break the for loop
break;
}
subscript++;
}
if (charisincheck == true) //if the char in string, then the count +1
{
counter[subscript] += 1;
}
else //if not, add the new char to check, and also add a counter for this new char
{
check.push_back(cstr);
counter.push_back(1);
}
}
for (decltype(counter.size()) i = 0; i != counter.size(); i++)
{
cout << check[i] << ":" << counter[i] << endl;
}met
import java.util.*;
class dublicate{
public static void main(String arg[]){
Scanner sc =new Scanner(System.in);
String str=sc.nextLine();
int d[]=new int[256];
int count=0;
for(int i=0;i<256;i++){
d[i]=0;
}
for(int i=0;i<str.length();i++){
if(d[str.charAt(i)]==0)
for(int j=i+1;j<str.length();j++){
if(str.charAt(i)==str.charAt(j)){
d[str.charAt(i)]++;
}
}
}
for(char i=0;i<256;i++){
if(d[i]>0)
System.out.println(i+" :="+(d[i]+1));
}
}
}
//here simple code for duplicate characters in a string in C++
#include<iostream.h>
#include<conio.h>
#include<string.h>
void main(){
clrscr();
char str[100];
cin>>str;
int d[256];
int count=0;
for(int k=0;k<256;k++){
d[k]=0;
}
for(int i=0;i<strlen(str);i++){
if(d[str[i]]==0)
for(int j=i+1;j<strlen(str);j++){
if(str[i]==str[j]){
d[str[i]]++;
}
}
}
for(int c=0;c<256;c++){
if(d[c]>0)
cout<<(char)c<<" :="<<(d[c]+1)<<"\n";
}
getch();
}

Stack Corruption error around the int array in c++

I am trying to write some c++ code that is a demo for a formula but using Recursion.
Here is my program and the error it throws.
Environment - Visual Studio 2012
Compilation - Successful
Runtime Exception -
Run-Time Check Failure #2 - Stack around the variable 'inputNumbers' was corrupted.
Code -
#include <stdlib.h>
#include <iostream>
using namespace std;
int FindNumber(int Numbers[],int index,int sum, int count)
{
if(count == 0)
return sum;
else if (count == 1)
{
sum -= Numbers[index-1];
index = index -1;
count = count-1;
return sum = FindNumber(Numbers,index,sum,count);
}
else
{
sum += Numbers[index-1];
index = index -1;
count = count-1;
return sum = FindNumber(Numbers,index,sum,count);
}
}
void main()
{
int inputNumbers[50]; //declare the series of numbers
int cnt = 0; //define and initailize an index counter for inserting the values in number series.
int position = 7; //defines the position of the number in the series whose value we want to find.
// insert the number series values in the int array.
for (int i = 1; i < 51; i++)
{
inputNumbers[cnt] = i;
cnt++;
inputNumbers[cnt] = i;
cnt++;
}
cnt=0;
for (int i = 1; i < 51; i++)
{
cout<<inputNumbers[cnt]<<endl;
cnt++;
cout<<inputNumbers[cnt]<<endl;
cnt++;
}
// set another counter variable to 3 since formula suggests that we need to substrat 3 times from the nth position
// Formula : nth = (n-1)th + (n-2)th - (n-3)th
cnt = 3;
int FoundNumber = 0;
//Check if position to be found is greater than 3.
if(position>3)
{
FoundNumber = FindNumber(inputNumbers,position,FoundNumber,cnt);
cout<< "The number found is : " << FoundNumber<< endl;
}
else
{
cout<<"This program is only applicable for finding numbers of a position value greater than 3..."<<endl;
}
}
The entire program is working perfect as per the logic I expect and gives proper output when i debug it but throw exception while exiting the main() after execution is complete.
I see i am doing a really silly but an intricate memory management mistake[and cannot find it].
Any help is appreciated.
Aren't you filling twice the size of the array here?
for (int i = 1; i < 51; i++)
{
inputNumbers[cnt] = i;
cnt++;
inputNumbers[cnt] = i;
cnt++;
}
For an array of length 50 you cannot access beyond element 49; so code should be like:
int inputNumbers[50]; //declare the series of numbers
int cnt = 0; //define and initailize an index counter for inserting the values in number series.
// insert the number series values in the int array.
for (int i = 0; i < 50; i++)
{
inputNumbers[cnt] = i;
cnt++;
}
And indeed as in the previous answer you probably want to increment cnt only once.