Check to see if an element exists in a 2D array C++ - c++

I am trying to check to see if an character element is in my output array. The array is getting the frequency of the characters in a string. So i want to say if the current character is in the array then add 1 to the frequency else add the character to the array with a frequency of 1. Also, I want the table to display the top 5 highest frequency's in order.
EX of what the table should look like:
character: a b c d
freqency: 1 2 3 4
string input = GetInputString(inputFileName);
char ** output;
for (int i = 0; i < sizeof(output); i++)
{
if (input [count] == output[i][]) // this is where my issue is
{
//.......
}
}

You could use std::vector<std::pair<char,int>> to store character and it's count.
string input("1212345678999");
std::vector<std::pair<char, int>> sp;
for(auto c : input)
{
auto it = std::find_if(sp.begin(), sp.end(),
[=](const pair<int, char>& p) {return p.first == c; });
if (it != sp.end())
{
it->second++; // if char is found, increase count
}
else
{
sp.push_back(std::make_pair(c, 1)); // new char, add an entry and initialize count to 1
}
}
To display the top 5 highest frequency's in order, you could sort by count in decent order:
std::sort(sp.begin(), sp.end(),
[](const pair<int, char>& p1, const pair<int, char>& p2)
{
return p1.second > p2.second;
});

Assuming your example means that 'a' is at 0,0, 'b' is at 0,2, 1 is at 1,0 etc, which means that the character is always in the first row, you just have to iterate through every entry of 0[x].
// you should declare your array as an array
char output[2][26] = {0}; // {0} initialises all elements;
// ... assign values to output.
// I assume there's a count loop here, that checks for the upper bounds of input.
// ...
// You have to determine how many columns there are somehow,
// I just made a static array of 2,26
const int columnsize = 26;
for (int i = 0; i < columnsize; i++)
{
if ( input[count] == output[0][i] )
{
// found the character
}
}
This is to make your implementation work, but there are better or at least easier ways to do this. For instance, if your array sizes aren't fixed at compile time, you could use a vector of vectors. Or if you just want to track the occurrences of characters, you could use a stl map of characters to frequency.

Related

How to generate a set of unique hash strings in C++?

This code produce 26*26*26*26 hasname (using combinations of a-z)or you can say random names which i want to assign to a structure member.Now when i am assigning that by first allocating that structure member sufficient memory and then using strcpy, only last hashname generated by this code is being passed to the structure i.e zzzz(it is the last hashname).What can i do so that hashname is assigned from the starting.
vcd_xyz[4] = '\0';
int count = 0;
for(int i=0;i<26;i++)
{
vcd_xyz[0] = 'a'+i;
for(int j=0;j<26;j++)
{
vcd_xyz[1] = 'a'+j;
for(int k = 0;k<26;k++)
{
vcd_xyz[2] = 'a' + k;
for(int l=0;l<26;l++)
{
vcd_xyz[3] = 'a' +l;
count ++;
printf("%s\n",vcd_xyz);
}
}
}
}
So i am using
sss->Variables[0].hashname = (char*)calloc(strlen((char*)vcd_xyz)+1,sizeof(char));
strcpy(sss->Variables[0].hashname,(char*)vcd_xyz);
to copy the hasname produced but it is copying the last hashname produced, so where ever i am using tr0->Variables[0].hashname = (char*)calloc(strlen((char*)vcd_xyz)+1,sizeof(char));
strcpy(tr0->Variables[0].hashname,(char*)vcd_xyz); only zzzz get printed.what i am doing wrong or what should i do so that hashname are assigned in a sequential manner.
At first you need to realize that char vcd_xyz[4] is an array of 4 characters, meaning that you can put there 3 characters + terminating character '\0'. If you treat this array as it is null-terminated when it is not, it results in undefined behavior.
What your code actually does is that it iterates through all possible combinations of 4 letters long strings, from "aaaa" to "zzzz", leaving the vcd_xyz array filled with the last combination (i.e. "zzzz").
If you want to generate random 4-letters long string, here's the C-style function you might use:
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
it generates random number from <min;max> interval and it can be used like this:
std::string generateHashTag() {
char str[5];
for (int i = 0; i < 4; ++i)
str[i] = irand('a', 'z');
str[4] = '\0';
return std::string(str);
}
But in case you want to generate a set of unique 4-letters long hash tags, you will need more complex solution. In C++ you might easily generate these strings in a loop that will put them into an std::set container till you have enough of them or you might generate more unique combinations of this string, put all of these into an std::vector, shuffle it and pick first N, e.g.:
const size_t N = 5;
std::set<std::string> myHashTags;
srand(time(0));
while (myHashTags.size() < N)
myHashTags.insert(generateHashTag());
for (std::set<std::string>::iterator i = myHashTags.begin();
i != myHashTags.end(); ++i)
std::cout << *i << ' ';
outputs kemy snwv vnmi wfmm wqeg. Full example here.

Is there a better (more efficient) way to find if a string can be formed from chars of another string?

This is interesting because it's a possible interview question, so it would be good to know the most efficient algorithm for this problem. I came up with a solution (which contains elements of other people's solutions) that requires a map<char, int> to store letters from the first string as keys, and numbers of their occurrences as values. The algorithm then looks through each letter in the container string and checks if there's already an entry in the map. If so, decrement its value until it's zero and so on; until the container is finished (failure), or until the mapis empty (success).
The complexity of this algorithm is O(n), O(n) being the worst-case scenario (failure).
Do you know a better way?
Here is the code that I've written, tested and commented:
// takes a word we need to find, and the container that might the letters for it
bool stringExists(string word, string container) {
// success is initially false
bool success = false;
// key = char representing a letter; value = int = number of occurrences within a word
map<char, int> wordMap;
// loop through each letter in the word
for (unsigned i = 0; i < word.length(); i++) {
char key = word.at(i); // save this letter as a "key" in a char
if (wordMap.find(key) == wordMap.end()) // if letter doesn't exist in the map...
wordMap.insert(make_pair(key, 1)); // add it to the map with initial value of 1
else
wordMap.at(key)++; // otherwise, increment its value
}
for (int i = 0; i < container.size() && !success; i++) {
char key = container.at(i);
// if found
if (wordMap.find(key) != wordMap.end()) {
if (wordMap.at(key) == 1) { // if this is the last occurrence of this key in map
wordMap.erase(key); // remove this pair
if (wordMap.empty()) // all the letters were found in the container!
success = true; // this will stop the for loop from running
}
else // else, if there are more values of this key
wordMap.at(key)--; // decrement the count
}
}
return success;
}
Do not use std::map. Usually it has O(log N) write, and O(log N) access. And malloc call on write.
For char you can use simple int freq[256] table (or std::vector if you are so inclined).
bool stringExists(const string& word, const string& cont) {
int freq[CHAR_MAX-CHAR_MIN+1]={0};
for (int c: cont) ++freq[c-CHAR_MIN];
for (int c: word) if(--freq[c-CHAR_MIN]<0) return false;
return true;
}
Complexity of this code is O(N + M), where N and M are: word.size() and cont.size(). And I would guess that it is at least 100 times faster even from small sized inputs.

How to find a unique number using std::find

Hey here is a trick question asked in class today, I was wondering if there is a way to find a unique number in a array, The usual method is to use two for loops and get the unique number which does not match with all the others I am using std::vectors for my array in C++ and was wondering if find could spot the unique number as I wouldn't know where the unique number is in the array.
Assuming that we know that the vector has at least three
elements (because otherwise, the question doesn't make sense),
just look for an element different from the first. If it
happens to be the second, of course, we have to check the third
to see whether it was the first or the second which is unique,
which means a little extra code, but roughly:
std::vector<int>::const_iterator
findUniqueEntry( std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end )
{
std::vector<int>::const_iterator result
= std::find_if(
next( begin ), end, []( int value) { return value != *begin );
if ( result == next( begin ) && *result == *next( result ) ) {
-- result;
}
return result;
}
(Not tested, but you get the idea.)
As others have said, sorting is one option. Then your unique value(s) will have a different value on either side.
Here's another option that solves it, using std::find, in O(n^2) time(one iteration of the vector, but each iteration iterates through the whole vector, minus one element.) - sorting not required.
vector<int> findUniques(vector<int> values)
{
vector<int> uniqueValues;
vector<int>::iterator begin = values.begin();
vector<int>::iterator end = values.end();
vector<int>::iterator current;
for(current = begin ; current != end ; current++)
{
int val = *current;
bool foundBefore = false;
bool foundAfter = false;
if (std::find(begin, current, val) != current)
{
foundBefore = true;
}
else if (std::find(current + 1, end, val) != end)
{
foundAfter = true;
}
if(!foundBefore && !foundAfter)
uniqueValues.push_back(val);
}
return uniqueValues;
}
Basically what is happening here, is that I am running ::find on the elements in the vector before my current element, and also running ::find on the elements after my current element. Since my current element already has the value stored in 'val'(ie, it's in the vector once already), if I find it before or after the current value, then it is not a unique value.
This should find all values in the vector that are not unique, regardless of how many unique values there are.
Here's some test code to run it and see:
void printUniques(vector<int> uniques)
{
vector<int>::iterator it;
for(it = uniques.begin() ; it < uniques.end() ; it++)
{
cout << "Unique value: " << *it << endl;
}
}
void WaitForKey()
{
system("pause");
}
int main()
{
vector<int> values;
for(int i = 0 ; i < 10 ; i++)
{
values.push_back(i);
}
/*for(int i = 2 ; i < 10 ; i++)
{
values.push_back(i);
}*/
printUniques(findUniques(values));
WaitForKey();
return -13;
}
As an added bonus:
Here's a version that uses a map, does not use std::find, and gets the job done in O(nlogn) time - n for the for loop, and log(n) for map::find(), which uses a red-black tree.
map<int,bool> mapValues(vector<int> values)
{
map<int, bool> uniques;
for(unsigned int i = 0 ; i < values.size() ; i++)
{
uniques[values[i]] = (uniques.find(values[i]) == uniques.end());
}
return uniques;
}
void printUniques(map<int, bool> uniques)
{
cout << endl;
map<int, bool>::iterator it;
for(it = uniques.begin() ; it != uniques.end() ; it++)
{
if(it->second)
cout << "Unique value: " << it->first << endl;
}
}
And an explanation. Iterate over all elements in the vector<int>. If the current member is not in the map, set its value to true. If it is in the map, set the value to false. Afterwards, all values that have the value true are unique, and all values with false have one or more duplicates.
If you have more than two values (one of which has to be unique), you can do it in O(n) in time and space by iterating a first time through the array and filling a map that has as a key the value, and value the number of occurences of the key.
Then you just have to iterate through the map in order to find a value of 1. That would be a unique number.
This example uses a map to count number occurences. Unique number will be seen only one time:
#include <iostream>
#include <map>
#include <vector>
int main ()
{
std::map<int,int> mymap;
std::map<int,int>::iterator mit;
std::vector<int> v;
std::vector<int> myunique;
v.push_back(10); v.push_back(10);
v.push_back(20); v.push_back(30);
v.push_back(40); v.push_back(30);
std::vector<int>::iterator vit;
// count occurence of all numbers
for(vit=v.begin();vit!=v.end();++vit)
{
int number = *vit;
mit = mymap.find(number);
if( mit == mymap.end() )
{
// there's no record in map for your number yet
mymap[number]=1; // we have seen it for the first time
} else {
mit->second++; // thiw one will not be unique
}
}
// find the unique ones
for(mit=mymap.begin();mit!=mymap.end();++mit)
{
if( mit->second == 1 ) // this was seen only one time
{
myunique.push_back(mit->first);
}
}
// print out unique numbers
for(vit=myunique.begin();vit!=myunique.end();++vit)
std::cout << *vit << std::endl;
return 0;
}
Unique numbers in this example are 20 and 40. There's no need for the list to be ordered for this algorithm.
Do you mean to find a number in a vector which appears only once? The nested loop if the easy solution. I don't think std::find or std::find_if is very useful here. Another option is to sort the vector so that you only need to find two consecutive numbers that are different. It seems overkill, but it is actually O(nlogn) instead of O(n^2) as the nested loop:
void findUnique(const std::vector<int>& v, std::vector<int> &unique)
{
if(v.size() <= 1)
{
unique = v;
return;
}
unique.clear();
vector<int> w = v;
std::sort(w.begin(), w.end());
if(w[0] != w[1]) unique.push_back(w[0]);
for(size_t i = 1; i < w.size(); ++i)
if(w[i-1] != w[i]) unique.push_back(w[i]);
// unique contains the numbers that are not repeated
}
Assuming you are given an array size>=3 which contains one instance of value A, and all other values are B, then you can do this with a single for loop.
int find_odd(int* array, int length) {
// In the first three elements, we are guaranteed to have 2 common ones.
int common=array[0];
if (array[1]!=common && array[2]!=common)
// The second and third elements are the common one, and the one we thought was not.
return common;
// Now search for the oddball.
for (int i=0; i<length; i++)
if (array[i]!=common) return array[i];
}
EDIT:
K what if more than 2 in an array of 5 are different? – super
Ah... that is a different problem. So you have an array of size n, which contains the common element c more than once, and all other elements exactly once. The goal is to find the set of non-common (i.e. unique) elements right?
Then you need to look at Sylvain's answer above. I think he was answering a different question, but it would work for this. At the end, you will have a hash map full of the counts of each value. Loop through the hash map, and every time you see a value of 1, you will know the key is a unique value in the input array.

Given a vector with integers from 0 to n, but not all included, how do I efficiently get the non-included integers?

Given a vector with integers from 0 to n, but not all included, how do I efficiently get the non-included integers?
For example if I have a vector with 1 2 3 5, I need to get the vector that contains 0 4.
But I need to do it very efficiently.
Since the vector is already sorted, this becomes trivial:
vector<int> v = {1,2,3,5};
vector<int> ret;
v.push_back(n+1); // this is to enforce a limit using less branches in the loop
for(int i = 0, j = 0; i <= n; ++i){
int present = v[j++];
while(i < present){
ret.push_back(i++);
}
}
return ret;
Additionally, if it wasn't sorted, you could either sort it and apply the above algorithm, or, if you know the range of n, and you can afford the extra memory, you could instead create an array of boolean (or a bitset) and mark the index corresponding to every element you encounter (e.g. bitset[v[j++]] = true;), subsequently iterating from 0 to n and inserting into your vector every element whose bitset position has not been marked.
Basically the idea presented here is that we know the number of missing items beforehand if we can assume sorted input without duplicate values.
Then it is possible to pre-allocate enough space to hold the missing values beforehand (no later dynamic allocation required). Then we can also exploit the possible shortcut when all missing values were found.
If the input vector is not sorted or contains duplicate values, a wrapper function can be used that establishes this precondition.
#include <iostream>
#include <set>
#include <vector>
inline std::vector<int> find_missing(std::vector<int> const & input) {
// assuming non-empty, sorted input, no duplicates
// number of items missing
int n_missing = input.back() - input.size() + 1;
// pre-allocate enough memory for missing values
std::vector<int> result(n_missing);
// iterate input vector with shortcut if all missing values were found
auto input_it = input.begin();
auto result_it = result.begin();
for (int i = 0; result_it != result.end() && input_it != input.end(); ++i) {
if (i < *input_it) (*result_it++) = i;
else ++input_it;
}
return result;
}
// use this if the input vector is not sorted/unique
inline std::vector<int> find_missing_unordered(std::vector<int> const & input) {
std::set<int> values(input.begin(), input.end());
return find_missing(std::vector<int>(values.begin(), values.end()));
}
int main() {
std::vector<int> input = {1,2,3,5,5,5,7};
std::vector<int> result = find_missing_unordered(input);
for (int i : result)
std::cout << i << " ";
std::cout << "\n";
}
The output is:
$ g++ test.cc -std=c++11 && ./a.out
0 4 6

Arranging by indexes vector

I have two vectors: a vector and index vector. How can I make the vector be arranged by the indexes vector? Like:
Indexes 5 0 2 1 3 4
Values a b c d e f
Values after operation b d c e f a
The indexes vector will always contain the range [0, n) and each index only once.
I need this operation to be done in place because the code is going to be run on a device with low memory.
How can I do this in c++? I can use c++11
Since you know that your index array is a permutation of [0, N), you can do this in linear time and in-place (plus one temporary) by working cycle-by-cycle. Something like this:
size_t indices[N];
data_t values[N];
for (size_t pos = 0; pos < N; ++pos) // \
{ // } this loops _over_ cycles
if (indices[pos] == pos) continue; // /
size_t i = pos;
const data_t tmp = values[pos];
while (true) // --> this loops _through_ one cycle
{
const size_t next = indices[i];
indices[i] = i;
values[i] = values[next];
if (next == pos) break;
i = next;
}
values[i] = tmp;
}
This implementation has the advantage over using swap each time that we only need to use the temporary variable once per cycle.
If the data type is move-only, this still works if all the assignments are surrounded by std::move().
std::vector<int> indices = { 5, 0, 2, 1, 3, 4};
std::vector<char> values = {'a', 'b', 'c', 'd', 'e', 'f'};
for(size_t n = 0; n < indices.size(); ++n)
{
while(indices[n] != n)
{
std::swap(values[n], values[indices[n]]);
std::swap(indices[n], indices[indices[n]]);
}
}
EDIT:
I think this should be O(n), anyone disagree?
for(int i=0;i<=indexes.size();++i)
for(int j=i+1;j<=indexes.size();++j)
if(indexes[i] > indexes[j] )
swap(indexes[i],indexes[j]),
swap(values[i],values[j]);
It's O(N²) complexity, but should work fine on small number values.
You can also pass a comparison function to the C++ STL sort function if you want O(N*logN)
You can just sort the vector, your comparison operation should compare the indices. Of course, when moving the data around, you have to move the indices, too.
At the end, your indices will be just 0, 1, ... (n-1), and the data will be at the corresponding places.
As implementation note: you can store the values and indices together in a structure:
struct SortEntry
{
Data value;
size_t index;
};
and define the comparison operator to look only at indices:
bool operator< (const SortEntry& lhs, const SortEntry& rhs)
{
return lhs.index < rhs.index;
}
This solution runs in O(n) time:
int tmp;
for(int i = 0; i < n; i++)
while(indexes[i] != i){
swap(values[i], values[indexes[i]]);
tmp = indexes[i];
swap(indexes[i], indexes[tmp]);
}
This will run in O(n) time without any error.Check it on ideone
int main(int argc, char *argv[])
{
int indexes[6]={2,3,5,1,0,4};
char values[6]={'a','b','c','d','e','f'};
int result[sizeof(indexes)/4]; //creating array of size indexes or values
int a,i;
for( i=0;i<(sizeof(indexes)/4);i++)
{
a=indexes[i]; //saving the index value at i of array indexes
result[a]=values[i]; //saving the result in result array
}
for ( i=0;i<(sizeof(indexes)/4);i++)
printf("%c",result[i]); //printing the result
system("PAUSE");
return 0;
}