adjacency list error with list - c++

Basically i generated a adj_matrix and i want to make an adj_list from the adj_matrix...However I keep getting an error saying "no match for call..."
i tried it without aPair i still get the same error i can't seem to figure out what my problem is. Can anyone tell me why list isn't working? the list is at the very end of the code
int **gen_random_graph(int n)
{
srand(time(0));
int **adj_matrix = new int*[n];
for(int i = 0; i < n; i++)
{
for (int j = i; j < n; j++) //generating a N x N matrix based on the # of vertex input
{
adj_matrix[i] = new int[n];
}
}
for(int u = 0; u < n; u++)
{
for (int v = u; v < n; v++)
{
bool edgeOrNot = rand() % 2; //decide whether it has an edge or not
adj_matrix[u][v] = adj_matrix[v][u] = edgeOrNot;
if(adj_matrix[u][v] == true)
{
adj_matrix[v][u] = true;
if(u == v) //We can't have i = j in an undirected graph so we set it to false
{
adj_matrix[u][v] = -1;
}
}
else //if adj_matrix[u][v] is false set the symmetry to be false
{
adj_matrix[v][u] = adj_matrix[u][v] = -1;
}
}
}
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++) //create the N x N with edges and sets the weight between the edge randomly
{
if(adj_matrix[i][j] == true)
{
int weight = rand() % 10 + 1;
adj_matrix[i][j] = adj_matrix[j][i] = weight;
cout << " ( " << i << "," << j << " ) " << "weight: " << adj_matrix[i][j] << endl;
}
}
}
for(int i = 0; i < n; i++)
{
vector<int> adj_list;
for(int j = i; j < n; j++)
{
if(adj_matrix[i][j] > 0)
{
int weight = adj_matrix[i][j];
adj_list.push_back(j);
cout << adj_list[i] << " " << endl;
}
}
}
print(n,adj_matrix);
return (adj_matrix);
}

I see that adj_list is not callable, so your code there is broken. There are a couple simple solutions to that. Taking a look at these docs, you may simply either access listObj.front() and listObj.back() OR you may also just create an iterator using listObj.begin() and iterating over the two elements (which may be desirable if you ever decide to put more than two elements in the list). See this tutorial for a simple example on creating an iterator for a list, in the code snippet right above the summary.
Note, here, your list object which I called listObj for simplicity/abstraction would simply be adj_matrix[i][j] in that bottom loop. That should fix your syntax error.
Also, aside from the syntax of your code, I don't get why you're trying to push weights to a list, then you're printing out and returning the adjacency matrix. I also don't get why you would use lists of pair objects when it seems like you only want to push integer weights onto it. For that, you can use a simple vector of integers (i.e.: vector <int> adj_list;)... or even simpler, you could use a simple array of integers... rather than using a vector of lists of pairs.
EDIT: After running the code locally and taking a look at the values, I realized the issue a bug in the OP's output was simply that he was using "true" in C++ in place of an integer, which was creating a bug, as explained in this SO post. The OP also has a further design decision to make where adjacency lists are concerned. More on what an adjacency list is, conceptually, found on Wikipedia.

Related

Program for finding the transpose of given matrix

I was thinking the approach to finding the transpose of a matrix and
below is the algorithm but it is not giving me proper output , so
anyone can tell me where I have done mistake and what should be proper
algorithm ? And how can I improve it ?
// m is the number of rows and n is the number of columns in a matrix
for (int i = 0; i < m; i++) // For swapping the non-diagonal elements
{
for (int j = 0; j < n; j++)
{
if (i != j)
{
int temp = 0;
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
}
cout << "Elements of transpose matrix of a is: " << endl;
for (int i = 0; i < m; i++) // printing the elements after transpose
{
for (int j = 0; j < n; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
You made the same mistake one can make while reversing a 1D array, hence I will use that as a simpler example:
#include <vector>
#include <iostream>
#include <utility>
std::vector<int> reverse_broken(std::vector<int> x){
for (size_t i=0;i< x.size(); ++i){
std::swap(x[i],x[x.size()-1-i]);
}
return x;
}
int main(){
auto x = reverse_broken({1,2,3,4});
for (const auto& e : x) std::cout << e << " ";
}
output:
1 2 3 4
reverse_broken iterates all elements and swaps them with the respective reversed element. However, once the first has been swapped with the last, the last has already been swapped. Later swapping the last with the first puts them in the original order again.
Same with your transpose. Once you swapped an element above the diagonal with one below the diagonal, they are already transposed. You don't need to swap them again.
I'll show you the fix for the reverse_broken and leave it to you to apply same fix to your transpose:
std::vector<int> reverse(std::vector<int> x){
for (size_t i=0;i< x.size()/2; ++i){
// stop in the middle ^^ because then all elements have been swapped
std::swap(x[i],x[x.size()-1-i]);
}
return x;
}
You should also consider to not transpose the matrix at all. Depending on how often you access swapped elements and how you populate it, it will be cheaper to either populate it in right order from the start, or just swapping the indices on access:
// normal access:
auto x = a[i][j];
// transposed access:
auto y = a[j][i];
PS: I used reverse only for illustration. To reverse a container you should actually use std::reverse. Also note that you can and should use std::swap. And last but not least, only a square matrix can be transposed in place. For a non square matrix you need to construct a new one with different dimensions.

C++ - Find sum of unique elements [duplicate]

This question already has answers here:
How to remove all instances of a duplicate from a vector<int> [duplicate]
(6 answers)
Closed 2 years ago.
I am trying to get the sum of unique elements, however I am not meeting the requirements of the given output.
//Prompted Input: [1,2,3,2]
//Expected output: 4
//Explanation: The unique elements are [1,3]
Below is my relevant code. Some things I have tried was to set j to i for the nested loop, however that changed nothing. The next step I took was to take out the first if conditional and have the code do the sum after finding the unique numbers but the output was 10. I'd be grateful if someone could give me a direction of where I'm messing up because I know I am close.
int sumOfUnique(vector<int>& nums) {
int sum = 0;
for(int i = 0; i < nums.size(); i++){
for(int j = 0; j < nums.size(); j++){
if(j == i){
sum += nums[i];
}
if(nums[i] == nums[j]){
break;
}
}
}
return sum;
}
You're close in that you have nested loops, but the content of the loops is not correct. The key is that you need to identify the unique elements, that's not something that your current code does.
Use the inner loop to identify if an element is unique and then after the inner loop add it to the sum if it is. Like this
int sumOfUnique(vector<int>& nums) {
int sum = 0;
for (int i = 0; i < nums.size(); i++) {
// count how many times nums[i] occurs
int count = 0;
for (int j = 0; j < nums.size(); j++)
if (nums[i] == nums[j])
++count;
if (count == 1) // is nums[i] unique?
sum += nums[i]; // add it to the sum if it is
}
return sum;
}
The trick is the extra variable count to work out if a particular number is unique.
You can make this code clearer and more flexible by putting the uniqueness test into it's own function. Like this
bool isUnique(vector<int>& nums, int i) {
// count how many times nums[i] occurs
int count = 0;
for (int j = 0; j < nums.size(); j++)
if (nums[i] == nums[j])
++count;
// return true if it occurs once only
return count == 1;
}
int sumOfUnique(vector<int>& nums) {
int sum = 0;
for (int i = 0; i < nums.size(); i++) {
if (isUnique(nums, i)) // is nums[i] unique?
sum += nums[i]; // add it to the sum if it is
}
return sum;
}
It's good to split code into different functions, with each function solving one part of the puzzle. Now (for instance) you could replace isUnique with a different function and sum values in your vector based on some different criterion.
There are more efficient solutions that this using std::set but I expect that the point of this exercise is to get you practising with loops and algorithms.
You can use std::map to create a frequency counter. After that, iterate through the map and check if a number only occurred once. If that's true, add that number to the result and afterward print out the final result.
int uniqueSum(vector<int> numbers)
{
map<int, int> frequency;
for (auto it = numbers.begin(); it!=numbers.end(); it++)
{
int value = (*it);
if (frequency.find(value) == frequency.end()) {frequency[value] = 1;}
else {frequency[value]++;}
//if value already occur in map then add 1 to its counter,
//else set its counter to 1
}
int sum = 0;
for (auto it = frequency.begin(); it!=frequency.end(); it++)
{
if (it->second == 1) {sum += it->first; }
//if the element appear just once in the vector, add it to sum, else skip it
}
return sum;
}
You can read more about map here: https://www.cplusplus.com/reference/map/map/
And also the find() function: https://www.cplusplus.com/reference/map/map/find/
Use a map to store numbers you have seen, and if they repeat, mark as not-viable.
int sumOfUnique(std::vector<int>& nums)
{
std::map<int, bool> seen;
for (auto i : nums)
{
auto it = seen.find(i);
if (it != seen.end()) // If already exists, set viability to false
{
it->second = false;
}
else { seen.insert({ i, true }); } // Does not exist, is currently viable
}
int sum = 0;
for (auto pair : seen)
{
if (pair.second) // If viable
{
sum += pair.first;
}
}
}

How to Compare multiple variables at the same time in the C++?

I'm making Sudoku validater program that checks whether solved sudoku is correct or not, In that program i need to compare multiple variables together to check whether they are equal or not...
I have provided a snippet of code, what i have tried, whether every su[][] has different value or not. I'm not getting expecting result...
I want to make sure that all the values in su[][] are unequal.
How can i achieve the same, what are mistakes in my snippet?
Thanks...
for(int i=0 ; i<9 ;++i){ //for checking a entire row
if(!(su[i][0]!=su[i][1]!=su[i][2]!=su[i][3]!=su[i][4]!=su[i][5]!=su[i][6]!=su[i][7]!=su[i][8])){
system("cls");
cout<<"SUDOKU'S SOLUTION IS INCORRECT!!";
exit(0);
}
}
To check for each column uniqueness like that you would have to compare each element to the other ones in a column.
e.g.:
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
for (int k = j + 1; k < 9; ++k) {
if (su[i][j] == su[i][k]) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
}
Since there are only 8 elements per row this cubic solution shouldn't give you much overhead.
If you had a higher number N of elements you could initialize an array of size N with 0 and transverse the column. For the i-th element in the column you add 1 to that elements position in the array. Then transverse the array. If there's a position whose value is different from 1, it means you have a duplicated value in the column.
e.g.:
for (int i = 0; i < N; ++i) {
int arr[N] = {0};
for (int j = 0; j < N; ++j)
++arr[su[i][j] - 1];
for (int i = 0; i < N; ++i) {
if (arr[i] != 1) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
This approach is way more faster than the first one for high values of N.
The codes above check the uniqueness for each column, you would still have to check for each row.
PS: I have not tested the codes, it may have a bug, but hope you get the idea.

how can I work with the last element of iterations

for(int t(0); t < 10;++t) { cout<<t<<endl;}
I'm just biginer in C++, and want to know how can I take the last elemnt of my "cout...."; in this case my laste element is 9
thx for help ;)
int c = 0;
for(int t = 0; t<10; t++)
{
c = t;
}
cout<<c;
This might be what you are looking for I am not sure I understand your question properly though.The variable c should hold the last element of t when the loop ends.
You can extract int t from the for loop :
int t;
for (t = 0; t < 10; ++t)
{
cout << t << endl;
}
int t = 9;
cout << t << endl;
Now you have the last element, #9.
ghagha, in C++ the ranges are run from 0 to n-1, in your example you have a range of 0 to < 10 hence 0 to 9, therefore your last element is 9. But as I said you can do any range as n-1 for the last element, provided that it follows normal conventions (it is possible to have a range from 1 to n if you code it that way)
It is not clear what you want but in any case your loop contains a bug. Instead of
for(int t(0); t < 10; t) { cout<<t<<endl;}
should be
for(int t(0); t < 10; t++) { cout<<t<<endl;}
that is variable t has to be incremented.
One simple way -
int t = 0;
for (; t < 10; ++t)
cout << t << ;
Tough the correct way to do it will be (one variable should not have two meanings, i.e 1. last element, 2. iterator context) -
int last_element;
for (int t = 0; t < 10; ++t;
{
cout << t << ;
last_element = t;
}

I cannot get code to separate and compare array data correctly

I've got an fstream input file that has [N] lines or items. I've written code to decide which items are triangles and which are rectangles and which are circles. I've got to isolate just the triangle items and then compare them to see if they are equal to +/- 0.1 the area of all the other triangle items. Then I have to cout the equal pairs of items as uppercase char letters.
Here's my code so far but it's not working correctly. It's outputting L&L, which is incorrect. It should say E&L because the two identical triangles in my array are on lines 5&12, Not 12&12. How do I fix this?
int ItmM = 0;
ItmN = 0;
int j = 0;
for (int i=0; i<M; i++)
{
if (btype[i] == Triangles)
{
TA[i] = (0.5 * (D[i] * E[i]));
for (int j=0; j<i; j++)
{
if (TA[i] - 0.1 < TA[j] && TA[j] < TA[i] + 0.1)
{
TA[j] = TA[i];
ItmM = i;
ItmN = j;
cout << "4. Triangular blocks that are the same size = "
<< (char)('A' + ItmM) << "&" << (char)('A' + ItmM)
<< endl;
}
}
}
}
I've edited the above code twice. It's still outputting L&L. Should be E&L, (5&12)
When you do TriangleAreaE = TrangleArea[j], and as j is always0, you are comparing every triangle with the first one. The 5th and 12th never get compared.
You should use a nested loop to compare every pair of triangles:
for (int i=0; i<M; i++)
{
if ( /*...*/ )
{
/*...*/
for (int j=0; j<i; j++)
{
// compare TriangleArea[i] with TriangleArea[j], if j is a triangle
}
}
}
You can fill in the detail, as this seems to be a homework problem.
And you should edit your existing posts instead of posting a new one.
The value of j never changes in the code you posted. You just compare the area of each triangle with the first one in the list. If I understand what you are trying to do correctly, you should be able to make it work with a nested for loop:
TriangleArea[0]= whatever
for(j=0; j<M; j++)
{
for(i=j+1;i<m;i++)
{
// rest of your code
In your code you never modify j, so you are always comparing with the first triangle (triangle A), so it's not really a suprise that it is equal to itself. What you need to do is loop over all already processed triangles and compare, so basically
for (int i=0; i<M; i++)
{
if (btype[i] == Triangles) //btype[i] declared earlier in larger code
{
TriangleArea[i] = (0.5 * (D[i] * E[i]));
for(int j = 0; j < i; ++j)
{
//Insert the comparison here
}
}
}
Of course your positioning of the cout will only print the last pair of equal sized pair, so judging from the text in your question, you might want to put the cout inside your loops.
(char)('A' + ItemNumberM) << "&" << (char)('A' + ItemNumberM)
This line prints the same item number twice. Is one of those supposed to be ItemNumberN?