Check if array index exists - c++

Is there any way to check if a given index of an array exists?
I am trying to set numerical index but something like 1, 5, 6,10. And so I want to see if these indexes already exist and if they do just increase another counter.
I normally work with php but I am trying to do this in c++, so basically I am trying to ask if there is an isset() way to use with c++
PS: Would this be easier with vectors? If so, can anyone point me to a good vector tutorial? Thanks

In C++, the size of an array is fixed when it is declared, and while you can access off the end of the declared array size, this is very dangerous and the source of hard-to-track-down bugs:
int i[10];
i[10] = 2; // Legal but very dangerous! Writing on memory you don't know about
It seems that you want array-like behavior, but without all elements being filled. Traditionally, this is in the realms of hash-tables. Vectors are not such a good solution here as you will have empty elements taking up space, much better is something like a map, where you can test if an element exists by searching for it and interpreting the result:
#include <map>
#include <string>
// Declare the map - integer keys, string values
std::map<int, std::string> a;
// Add an item at an arbitrary location
a[2] = std::string("A string");
// Find a key that isn't present
if(a.find(1) == a.end())
{
// This code will be run in this example
std::cout << "Not found" << std::endl;
}
else
{
std::cout << "Found" << std::endl;
}
One word of warning: Use the above method to find if a key exists, rather than something like testing for a default value
if(a[2] == 0)
{
a[2] = myValueToPutIn;
}
as the behavior of a map is to insert a default constructed object on the first access of that key value, if nothing is currently present.

My personal vote is for using a vector. They will resize dynamically, and as long as you don't do something stupid (like try and access an element that doesn't exist) they are quite friendly to use.
As for tutorials the best thing I could point you towards is a google search

To do this without vectors, you can simply cross-check the index you are tying to access with the size of array. Like: if(index < array_size) it is invalid index.
In case the size is not known to you, you can find it using the sizeof operator.
For example:
int arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
int arr_size = sizeof(arr)/sizeof(arr[0]);

It sounds to me as though really a map is closest to what you want. You can use the Map class in the STL (standard template library)(http://www.cppreference.com/wiki/stl/map/start).
Maps provide a container for objects which can be referenced by a key (your "index").

Related

Using "find" to access a value in vector

So I have been brushing up a bit on c++ and found out I am very rusty in comparison to my other languages. I have been working on this problem from codewars.com
Given a list lst and a number N, create a new list that contains each number of lst at most N times without reordering. For example if N = 2, and the input is [1,2,3,1,2,1,2,3], you take [1,2,3,1,2], drop the next [1,2] since this would lead to 1 and 2 being in the result 3 times, and then take 3, which leads to [1,2,3,1,2,3].
To accomplish this task I wanted to create a multidimentional vector to hold unique values of the provided list in the first dimension and corresponding number of occurences in the second dimension. However, I was unfamiliar with c++'s syntax to accomplish this, so I just made 2 separate vectors.(instances, countOfInstance)
Essentially what my algorithm will do is:
loop through the provided array(arr)
check to see if the value in "arr" does not exists in "instances"
If not found then push the value in "arr" to "instances",
add a counting value of 1 that corresponds to this index in "countOfInstance"
and then add the value in "arr" to the nFilteredVector.
If the value in "arr" is found in "instances" then:
Find the index value of "arr" in "instances"
Use this index to find its corresponding count value in "countOfInstances"
Determine if the count is less than the provided "N"
if less than "N" add to "nFilteredVector"
Then increment the value in "countOfInstances"
However, when I try to access the index of "CountOfInstances" with index of "instances" i get an odd error
no viable overloaded operator[] for type 'std::vector'
if (countOfInstances[std::find(instances.begin(), instances.end(),arr[i])] <=2){
Correct me if I am wrong, but it is my understanding that the find function returns the index value of the found element. I was wanting to use that index value to access "countOfInstances" vector.
Can someone please help me figure out the correct syntax of what I am looking for. Bonus points for integrating "instances" and "countOfInstance" as a multidimentional vector!!
#include <algorithm>
std::vector<int> deleteNth(std::vector<int> arr, int n)
{
std::vector<int> nFilteredVector;
std::vector<int> instances;
std::vector<int> countOfInstances;
for (int i =0; i < arr.size();i++){
if(std::find(instances.begin(), instances.end(),arr[i])==instances.end()){//value not found need to add corresponding value to instances vector then add an element of 1 to the correpeonding index of the countOfInstance vector.
instances.push_back(arr[i]);
countOfInstances.push_back(1);
nFilteredVector.push_back(arr[i]);
}else{ // value is found just need to increment the value in countOfInstances
//find the instance of the value in arr in the instance vector, use that value to find the corresponding value in countOfInstance
if (countOfInstances[std::find(instances.begin(), instances.end(),arr[i])] <=n){
nFilteredVector.push_back(arr[i]);
}
countOfInstances[std::find(instances.begin(), instances.end(),arr[i])]++;
}
return nFilteredVector;
}
Here are some examples of what codewars will be testing for
{
Assert::That(deleteNth({20,37,20,21}, 1), Equals(std::vector<int>({20, 37, 21})));
Assert::That(deleteNth({1,1,3,3,7,2,2,2,2}, 3), Equals(std::vector<int>({1, 1, 3, 3, 7, 2, 2, 2})));
}
If what you are trying to achieve is get the index of the found item in a std::vector, the following does this job using std::distance:
#include <algorithm>
#include <vector>
auto iter = std::find(instances.begin(), instances.end(),arr[i]);
if ( iter != instances.end())
{
// get the index of the found item
auto index = std::distance(instances.begin(), iter);
//...
}
I believe std::find return an iterator on instances. You cannot use an iterator from one list on another and you cannot use an iterator as an index.
What you could do is use
std::find(instances.begin(), instances.end(), arr[i]) - instances.begin()
as your index. This is a bit ugly, so you might also want to look a bit more at iterators and how to use them.

C++, How to use maps for holding multiple integer values

I'm working on a word Tagging system for a C++ project. I need a system where a map stores the following key-value information:
word["with"] = 16, 6, 15;
Where ["with"] is the index, and the 3-tuple (16, 6, 15) are values of the index. I've tried maps, but I keep getting semantic errors, which I understand are a result of not being able to give a key more then 1 value.
I tried multi maps, but I can't seem to get the syntax to suit my needs?
I would like to refrain from using Structs or Classes, as this database already contains 200 words, and I'm trying to keep my lines of code readable and too a minimum.
How would I go about this? Am I missing something? How would you declare a system like this?
You should declare your map as std::map<std::string, std::vector<unsigned int>>, so you can have a vector of values for your index.
You can make a map that maps Strings to Vectors or some other data structure that can hold an arbitrary number of integers.
Worth noting, however, that things like Structs and Classes are components of a language meant to organize code. Structs group related data; classes model groups of related data and their associated behaviors. It's certainly possible to do everything without them but that would make for some very unreadable code.
The number of lines and whether or not you use classes/structs are poor metrics for the complexity and readability of your code. And the modularity they offer far exceeds the minute runtime cost of dereferencing those values.
word["with"] = 16, 6, 15;//This usage is wrong
std::multimap or std::unordered_multimap should work for you.
If you define word as follows:
std::multimap<std::string,int> word;
You should insert values to map as shown below:
std::string key="with";
word.insert(std::pair<std::string,int>(key,16));
word.insert(std::pair<std::string,int>(key,6));
word.insert(std::pair<std::string,int>(key,15));
for( auto &x : word)
std::cout<<x.first<<" " << x.second<<"\n";
As user4581301 pointed out in comment if you have C++11 enabled compiler, you can insert values into std::multimap as follows:
word.emplace("with",16);
word.emplace("with",6);
word.emplace("with",15);
Demo: http://coliru.stacked-crooked.com/a/c7ede5c497172c5d
Example for using C++ maps to hold multiple integer values:
#include<iostream>
#include<map>
#include<vector>
using namespace std;
int main(){
std::map<int, std::vector<int> > mymap2;
std::vector<int> myvector;
myvector.push_back(8);
myvector.push_back(11);
myvector.push_back(53);
mymap2[5] = myvector;
cout << mymap2[5][0] << endl;
cout << mymap2[5][1] << endl;
cout << mymap2[5][2] << endl;
}
Prints:
8
11
53
Just replace the int datatypes with a string and you should be able to map strings to lists of numbers.

implementing BFS using STL in c++

I am trying to write a code for BFS in c++ using STL. This is the section of the code i am having trouble with
std::list<int> li=*i;
for (std::list<int>::iterator iter=li.begin(); iter!=li.end();++iter)
{
if (arr[iter]==0)
{
myQ.push(iter);
arr[iter]=1;
Here arr is the array that stores whether or not i have seen the node .i am getting the error
"No match for operator arr[] in arr[iter]
iter is an iterator, so a kind of pointer, not an integer. THis is whiy arr[] does not work, because it expects an integer.
Try with arr[*iter] instead, and your breadth first search will avoid the cycles succesfully.
Please note that you have the same potential issue with your push(iter), if myQ is supposed to contain nodes as well.
You could further improve your design, by defining arr as a set instead of an array/vector.
Your condition would then look like:
if (arr.count(*iter) == 0) {
myQ.push_back(*iter);
arr.insert(*iter); // works for int, but also other data types
}
Iam answering by assuming arr in an integer array.
Any array elemet can be accessed by its integer index only,but not address of integer index.
Here iter is the pointer which can store the address of an integer.
So you have to use '*' to retrieve the value stored at the address to get integer value.
So change array[iter] to array[*iter]..
Hope this will fix your problem.
Here iter is an iterator which is pointer to the list, so for accessing its value you have to write *iter(access value which it is pointing) instead of iter(it is reference).
Try this
std::list<int> li=*i;
for (std::list<int>::iterator iter=li.begin(); iter!=li.end();++iter)
{
if (arr[*iter]==0)
{
myQ.push(*iter);
arr[*iter]=1;

How to make a variable name without creating an array in C++?

How do you make a variable name where you create a variable and then in brackets the variable number? (By the way, I'm just guessing out how the code should be so that you get what I'm trying to say.) For example:
int var[5];
//create a variable var[5], but not var[4], var[3], var[2], etc.
Then, the variable number must be able to be accessed by a variable value:
int number = 5;
int var[number]; //creates a var[5], not a var[4], etc.
int var[2]; //creates a var[2], not a var[1], etc.
cout >>var[number];
number = 2;
cin << var[number];
If I'm way off track with my "example", please suggest something else. I need something similar to this for my game to operate, because I must be able to create an unlimited instance of bullets, but they will also be destroyed at one point.
It looks like you are looking for the functionality provided by std::map which is a container used to map keys to values.
Documentation of std::map
Example use
In the below example we bind the value 123 to the integer key 4, and the value 321 to key 8. We then use a std::map<int,int>::const_iterator to iterate over the key/value pairs in our std::map named m.
#include <map>
...
std::map<int, int> m;
m[4] = 123;
m[8] = 321;
for (std::map<int, int>::const_iterator cit = m.begin (); cit != m.end (); ++cit)
std::cout << cit->first << " -> " << cit->second << std::endl;
output:
4 -> 123
8 -> 321
It looks like you want variable length arrays, which is not something C++ supports. In most cases, the correct solution is to use an std::vector instead, as in
int number = 42; // or whatever
std::vector<int> var(number);
You can use std::vector as you would use an array in most cases, and you gain a lot of bonus functionality.
If I understand what you want correctly (which I'm not certain that I do), you want to be able to create a place to hold objects and use them according to some index number, but to only create the specific objects which go in it on demand. You want do to this either because 1) you don't know how many objects you're going to create or 2) you aren't going to use every index number or 3) both.
If (1) then you should probably just use a vector, which is an array-like structure which grows automatically as you add more things to it. Look up std::vector.
If (2) then you could use an array of pointers and initially set all of the values to null and then use new to create the objects as needed. (Or you could use the solution recommend in part 3.)
If (3) then you want to use some form of map or hash table. These structures will let you find things by number even when not all numbers are in use and will grow as needed. I would highly recommend a hash table, but in C++, there isn't one in the STL, so you have to build your own or find one in a third-party library. For ease, you can use std::map, which is part of the STL. It does basically the same thing, but is slower. Some C++ distributions also include std::hash_map. If it's available, that should be used instead because it will be faster than std::map.

Find Key in Stl Hash_map

I am beginner in c++ and have some problem with hash table. I need a Hash table structure for my program. first I use boost unordered_map. it have all things that I need, but it make my program so slow. then I want to test stl hash_map, but I can't do all thing that I need. this is my first code ( this is sample)
#include <hash_map>
using namespace std;
struct eqstr
{
bool operator()(int s1, int s2) const
{
return s1==s2;
}
};
typedef stdext::hash_map< int, int, stdext::hash_compare< int, eqstr > > HashTable;
int main()
{
HashTable a;
a.insert( std::pair<int,int>( 1, 1 ) );
a.insert( std::pair<int,int>( 2, 2 ) );
a.insert( std::pair<int,int>( 4, 4 ) );
//next i want to change value of key 2 to 20
a[2] = 20;
//this code only insert pair<2,20> into a, buy when I use boost unordered_map this code modify previous key of 2
//next I try this code for delete 2 and insert new one
a.erase(2);//this code does work nothing !!!
//next I try to find 2 and delete it
HashTable::iterator i;
i = a.find(2);//this code return end, and does not work!!!
a.erase(i);//cause error
//but when I write this code, it works!!!
i=a.begin();
a.erase(i);
//and finally i write this code
for (i = a.begin(); i!=a.end(); ++i)
{
if (i->first == 2 )
break;
}
if (i!= a.end())
a.erase(i);
//and this code work
but if i want to search over my data, i use array not hash_map, why I can't access, modity and delete from hash_map with o(1)
what is my mistake, and which hash structure is fast for my program with many value modification in initializing phase. is google sparse_hash suitable for me, if it is, can give me some tutorial on it.
thanks for any help
You may look at: http://msdn.microsoft.com/en-us/library/525kffzd(VS.71).aspx
I think stdext::hash_compare< int, eqstr > is causing the problems here. Try to erase it.
Another implementation of a hash map is std::tr1::unordered_map. But I think that performance of various hash map implementation would be similar. Could you elaborate more about how slow the boost::unordered_map was? How did you use it? What for?
There are so many different varieties of hash map and many developers still write their own because you can so much more often get a higher performance in your own one, written to your own specific use, than you can from a generic one, and people tend to use hash when they want a really high performance.
The first thing you need to consider is what you really need to do and how much performance you really need, then determine whether something ready-made can meet that or whether you need to write something of your own.
If you never delete elements, for example, but just write once then constantly look-up, then you can often rehash to reduce collisions for the actual set you obtain: longer at setup time but faster at lookup.
An issue in writing your own will occur if you delete elements because it is not enough to "null" the entry, as another one may have stepped over yours as part of its collision course and now if you look that one up it will give up as "not found" as soon as it hits your null.