I have made the following program in c++. I just want to print an array elements. My code is as follows:
#include <iostream>
#include <cstdio>
using namespace std;
#define n 5
double dist[n][n];
void read_distances()
{
for(int i = 0; i < n ; i++)
{
for (int j = 0 ;j < n; j++)
{
cout<<dist[i][j]<<" ";
}
cout<<"\n";
}
}
main()
{
double dist[n][n] =
{
{0, 20, 30, 10, 11},
{15, 0, 16, 4, 2},
{3, 5, 0, 2, 4},
{19, 6, 18, 0, 3},
{16, 4, 7, 16, 0}
};
read_distances();
}
I just wanted to print the dist[][] array inside the read_distances() function. But here I am getting all the values 0 as output. what's the reason of this?
The reason is because you declared the dist array in main(), and you initialized its contents, but the function read_distances() prints the values of a global array called dist. It happens to have the same name as the dist array in main()'s scope, but is a completely different array, and it is never initialized.
EDIT: you asked how to make it work. The easiest way is to pass it as a parameter. After removing the global declaration:
void read_distances(double dist[n][n])
{
// ...
}
and then in your main():
read_distances(dist);
(technically, the parameter to read_distances() is actually double (*)[n], but that's going to be a topic for another day and I didn't want to make this too confusing).
How about this:
#include <iostream>
#include <cstdio>
using namespace std;
#define n 5
void read_distances(double dist[n][n])
{
for(int i = 0; i < n ; i++)
{
for (int j = 0 ;j < n; j++)
{
cout<<dist[i][j]<<" ";
}
cout<<"\n";
}
}
int main()
{
double dist[n][n] =
{
{0, 20, 30, 10, 11},
{15, 0, 16, 4, 2},
{3, 5, 0, 2, 4},
{19, 6, 18, 0, 3},
{16, 4, 7, 16, 0}
};
read_distances(dist);
}
Your code doesn't work because you overshadowed the global version of dist with the local one you created at main. So you either not use a global one, like I do here, and pass the one you create at main() to your printing function; or you fill that array without creating a new array in main().
I'm trying to convert some old C functions to C++. My original programme stores a matrix in a single array, and I just pass a pointer to the first element to a function so that I am working on the correct row, e.g.
double f1(int *a){
return a[0] + a[1];
}
int main(void){
int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(i = 0; i < 5; i++){
printf("%d\n", f1(&x[2 * i]));
}
I would like to be able to do something similar using the STL without copying. So my programme would look something like this
double f1(vector<int>& a){
return a[0] + a[1];
}
int main(void){
int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
vector<int> y(x, x + 10);
for(i = 0; i < 5; i++){
cout << f1(y) << endl; // This is clearly wrong
}
How would I do this? I could change my function to receive a reference to a vector::iterator I guess, but is there another way?
You could simply pass an iterator to the function. Random access iterators are very similar to pointers (in fact, pointers qualify as random access iterators.) For example,
#include <vector>
double f1(std::vector<int>::const_iterator a)
{
return a[0] + a[1];
}
#include <iostream>
int main()
{
vector<int> y{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto it = y.cbegin();
for(int i = 0; i < y.size()/2; ++i)
std::cout << f1(it + 2*i) <<std::endl;
}
Write array view. An array view is a pair of pointers with begin end size empty, operator[], front and back methods, and constructors from C arrays, std::array<T,N>&, std::vector<T,A>&, std::vector<non_const_T,A>const&, std::array<non_const_T,N>const&, std::initializer_list<non_const_T>, etc.
Oh, and T*,size_t and T*,T* ctors, which are great for slicing (use forwarding ctors: T*,size_t->T*,T*, and everything else to those 2).
It does not own its data, so all of its methods are const except operator=. (non-const methods would be methods that change the view range -- changing the elements is a const operation on a view).
Then
double f1(array_view<const int> a){
return a[0] + a[1];
}
You don't need to make so many changes:
double f1(int *a)
{
return a[0] + a[1];
}
int main(void)
{
vector<int> y = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < 5; i++) {
cout << f1(&y[2 * i]) << endl;
}
}
Q:
arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9}
Ans:
values[]={1,2,5,6,7,9}
Q:
arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9}
Ans:
values[]={1,2,5,6,7,9,101,1502}
here is what i tried but not working
for(int i=0;i<(index-1);i++) {
if(data[i].age != data[i+1].age) {
c=new list;
c->value=data[i].age;
c->next=NULL; clas++;
if(age_head==NULL) {
p=c; age_head=c;
}
for(c=age_head;c!=NULL,c->next!=NULL;p=c,c=c->next) {
if(data[i].age!=c->value)
found=false;
else
found=true;
}
if((age_head!=NULL)&& (found=false)) {
p->next=c; c->next=NULL;
}
}
}
This is not the most efficient, but it has some values:
It uses STL objects
It uses a cool little known template trick for knowing at compile time the size of your C-like arrays
...
int a[] = {1,1,1,2,5,5,6,6,6,6,8,7,9} ;
int b[] = {1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9} ;
// function setting the set values
template<size_t size>
void findDistinctValues(std::set<int> & p_values, int (&p_array)[size])
{
// Code modified after Jacob's excellent comment
p_values.clear() ;
p_values.insert(p_array, p_array + size) ;
}
void foo()
{
std::set<int> values ;
findDistinctValues(values, a) ;
// values now contain {1, 2, 5, 6, 7, 8, 9}
findDistinctValues(values, b) ;
// values now contain {1, 2, 5, 6, 7, 8, 9, 101, 1502}
}
Another version could return the set, instead of taking it by reference. It would then be:
int a[] = {1,1,1,2,5,5,6,6,6,6,8,7,9} ;
int b[] = {1,1,1,2,5,5,6,6,6,6,8,7,9,101,1502,1502,1,9} ;
// function returning the set
template<size_t size>
std::set<int> findDistinctValues(int (&p_array)[size])
{
// Code modified after Jacob's excellent comment
return std::set<int>(p_array, p_array + size) ;
}
void foo()
{
std::set<int> valuesOne = findDistinctValues(a) ;
// valuesOne now contain {1, 2, 5, 6, 7, 8, 9}
std::set<int> valuesTwo = findDistinctValues(b) ;
// valuesTwo now contain {1, 2, 5, 6, 7, 8, 9, 101, 1502}
}
The first thing I spot in your code is
if((age_head!=NULL)&& (found=false)) {
you use assignment (=) instead of equality (==). The expression should be
if((age_head!=NULL)&& (found==false)) {
Then, in this loop
for(c=age_head;c!=NULL,c->next!=NULL;p=c,c=c->next) {
you are looking for a value in the list. However, in its current form, when the loop terminates, found will show whether the last element in the list equals to c->value. You need to check for found in the loop condition (and you need to AND the expressions instead of listing them separated by comma!):
for(c=age_head, found = false; !found && c!=NULL && c->next!=NULL; ...) {
The result of the comma operator is the result of the last subexpression inside - this is definitely not what you want. Moreover, with comma all subexpressions are evaluated, which results in dereferencing a null pointer if c == NULL - whereas the && operator is evaluated lazily, thus c->next!=NULL is evaluated only if c != NULL.
The next thing is that you need to search for the value in the list before you add it to the list! Also note that you are trying to check for two different things: that the actual data element is different from the next one, and that its value is not yet added to the list. The second condition is stronger - it will always work, while the first only works if the input data is ordered. So you can omit the first check altogether. The result of all the above, plus some more simplifications and clarifications, is
for(int i=0;i<index;i++) {
for(list* c=age_head, found=false; !found&&c&&c->next; p=c,c=c->next) {
if(data[i].age==c->value)
found=true;
}
if(!found) {
list* newc=new list;
newc->value=data[i].age;
newc->next=NULL;
clas++;
if(age_head==NULL) {
p=newc; age_head=newc;
} else {
p->next=newc; newc->next=NULL;
}
}
}
I still don't guarantee that your linked list handling logic is right though :-) In its current form, your code is hard to understand, because the different logical steps are not separated. With a bit of refactoring, the code could look a lot clearer, e.g.
for(int i=0;i<index;i++) {
if(!foundInList(data[i].age)) {
addToList(data[i].age);
}
}
Of course the simplest and most efficient would be using STL containers/algorithms instead, as shown in other answers. But I think there is much more educational value in improving your first attempt :-)
If the output need not to be sorted, you can use a Hashtable.
E.g. something like this:
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
#include <boost/unordered_set.hpp>
#include <vector>
using namespace std;
using namespace boost;
int main() {
int arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9};
size_t n = sizeof(arr1)/sizeof(int);
unordered_set<int> h;
for (size_t i = 0; i < n; ++i)
h.insert(arr1[i]);
vector<int> values;
foreach(int a, h)
values.push_back(a);
return 0;
}
The runtime is then in O(n).
An alternative to that is sorting the array and then to eliminate neighboring identical elements (advantage only STL is needed). But then the runtime is in O(n log n):
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int arr1[]={1,1,1,2,5,5,6,6,6,6,8,7,9};
size_t n = sizeof(arr1)/sizeof(int);
sort(arr1, arr1+n);
int *end = unique(arr1, arr1+n);
vector<int> values(arr1, end);
return 0;
}
Easily done using STL.
int array[] = { 1, 1, 2, 2, 1, 3, 3, 4, 5, 4, 4, 1, 1, 2 };
int nElements = sizeof(array)/sizeof(array[0]);
std::sort(&array[0], &array[nElements]);
int newSize = std::unique(&array[0], &array[nElements]) - &array[0];
first you need to sort the array and than do something like this:
for(int i = 0; i < size -1; i++)
{
if(array[i]!=array[i+1])
unique++;
// store it wherever you want to.
stored.push(array[i]);
}
#include <vector>
#include <algorithm>
#include <iostream>
int
main ()
{
int array[] = { 1, 1, 2, 2, 1, 3, 3, 4, 5, 4, 4, 1, 1, 2 };
std::vector < int >values;
values.push_back (array[0]);
for (int i = 1; i < sizeof (array) / sizeof (int); ++i)
{
std::vector < int >::iterator it =
std::find (values.begin (), values.end (), array[i]);
if (it == values.end ())
values.push_back (array[i]);
}
std::cout << "Result:" << std::endl;
for (int i = 0; i < values.size (); i++)
std::cout << values[i] << std::endl;
}
This seems to be a duplicate of Removing duplicates in an array while preserving the order in C++
While the wording of the question is different, the result is the same.
Based on above ideas/codes, I am able to accomplish my job on finding distinct values in C++ array. Thanks every one who replied on this thread.
#include <set>
#include <iostream>
using namespace std;
// function setting the set values
template<size_t size>
void findDistinctValues(std::set<int> & p_values,int (&p_array)[size])
{
// Code modified after Jacob's excellent comment
p_values.clear() ;
p_values.insert(p_array, p_array + size) ;
}
void findDistinctValues2( int arr[],int size)
{
std::set<int> values_1 ;
std::set<int>::iterator it_1;
values_1.clear();
values_1.insert(arr,arr+size);
for (it_1=values_1.begin(); it_1!=values_1.end(); ++it_1)
std::cout << ' ' << *it_1<<endl;
}
int main()
{
int arr[] = {1,6100,4,94,93,-6,2,4,4,5,5,2500,5,4,5,2,3,6,1,15,16,0,0,99,0,0,34,99,6100,2500};
std::set<int> values ;
std::set<int>::iterator it;
int arr_size = sizeof(arr)/sizeof(int);
printf("Total no of array variables: %d\n",arr_size);
printf("Output from findDistinctValues (function 1)\n ");
findDistinctValues(values, arr) ;
for (it=values.begin(); it!=values.end(); ++it)
std::cout << ' ' << *it<<endl;
std::cout<<endl;
std::cout<<values.size()<<endl; //find the size of distict values
printf("Output from findDistinctValues (function 2) \n ");
findDistinctValues2(arr,arr_size);
getchar();
return 0;
}