EDITED :
#include<iostream>
using namespace std;
#include<conio.h>
#include<string.h>
void dfsvisit(int a[][30], int i, const char *color[])
{
int v;
int p[30];
int f[30]={};
static int j=1;
color[i]="gray";
for(v=1;v<31;v++)
while(a[i][v]!=0)
if(!strcmp(color[a[i][v]],"white"))
{
p[a[i][v]]=i;
dfsvisit(a,i,color);
}
color[i]="black";
j++;
f[i]=1;
cout<<f[i]<<" ";
}
int main()
{
int a[][30]={{2, 16},{4, 8},{5, 16, 21},{1, 2},{1, 9, 27},{1, 10, 15},{4, 6, 11, 12},{4, 16},{2, 19, 29},{3, 14, 28},{3, 13, 15, 17},{8, 9, 18, 26},{1, 7, 10, 19},{5, 8, 20, 24},{3, 21, 29},{1, 2, 8},{16, 23, 28, 29},{4, 12, 21, 24}, {3, 15, 16},{2, 3, 6, 22},{4, 15, 25},{4, 6, 20, 24},{9, 10, 11, 12},{19, 26, 30},{2, 27, 29},{1, 28, 29, 30},{8, 16, 29},{6, 10, 30},{19, 21, 27},{1, 2, 3, 22}};
int i;
const char *color[30];
for(i=1;i<31;i++)
color[i]="white";
for(i=1;i<31;i++)
if(!strcmp(color[i],"white"))
dfsvisit(a,i,color);
return 0;
}
Just want to make sure if I am using const char c correct? If yes, where else have I done the mistake? I am trying to run it on codeblocks. It compiles well, but when I try to run it, it shows program has stopped working.
Thanks.
Change:
for(i=1;i<=30;u++)
to:
for (i = 0; i < 30; i++)
You're comparing pointers to constant strings, which may or may not be equal when the strings are equal. Use an enum for this kind of algorithm:
enum { BLACK, GRAY, WHITE };
First of all, your for loop is incorrect, it should be like this:
for(i = 0; i < 30; i++)
Second, your array int a[][30] should be like int a[30][] (30 elements of 2, 3 or 4 integers).
Third, you can't pass an array like this, use a pointer.
Well, this code is not clear, and the recursive function could make a stack overflow.
I hope it will help you.
You say that this:
for(i=1;i<=30;u++)
compiles?
I suggest changing the u to an i...
EDIT:
OK, so you say the u was a typo.
Next step: start the thing in a debugger, wait for it to loop, break into it and step through.
That should tell you where something happens to your loop variable.
EDIT 2:
< niggle >
I second everybody who suggests you use std::string. You might consider dropping the irregular arrays in favor of std::vectors of std::vectors, which, through the use of iterators, would have caught the fencepost error in your loop for you. In general, the STL vector is safer and more comfortable than an array while being just as fast and small.
And while were at it, it is best practice to declare your loop variables within the for instead of at the beginning of the function scope (RAII). Unless, of course, you need that value after the loop.
< /niggle >
EDIT 3:
For more on std::string, std::vector and std::otherStuff: the book Accelerated C++ gives a good introduction to C++ and especially the STL. Concepts like char* or arrays only come up quite late, after the STL-way of doing things has been safely covered and practiced. I'd really like to see something like that for the Boost library...
You want to use strcmp instead of == for your string comparison.
However, it's not clear why this would hang. You've removed the code that could have this go into an infinite loop.
No, you are not correctly using C style strings (char *). Give it up and use std::string instead.
For example:
const char *color[30];
for(i=1;i<31;i++)
color[i]="white";
The above fragment copies pointers and does not make duplicates of the text. This may or may not be what you wanted.
Rewritten more safely:
const char * color[30]; // 30 pointers to char.
const char text_white[] = "white";
for (i = 0; i < 30; ++i) // Note addition of spaces
{
color[i] = text_white;
}
The const char text_white[] declares a pointer, text_white, to constant data. This will let the compiler know when you try to assign to the literal.
The C++ code for this:
typedef std::vector<std::string> Text_Container;
Text_Container texts;
const std::string white_text("white");
const unsigned int MAX_TEXTS = 30;
for (i = 0; i < MAX_TEXTS; ++i)
{
texts[i] = white_text; // Makes a copy of the string.
}
Give up on char * for text unless your program needs to conserve memory. Prefer std::string and std::vector.
Related
In the task it was said that it is necessary to get the "value" of the largest elements from the array. Then it should be compared with the second array, and duplicates should be excluded.
In the task it is necessary to use partial_sort_copy in vector, and set_difference.
The problem is that when you start the program crashes at all, even without showing what exactly the error is, that's why I am writing here
I looked at several sites with examples of using this function, but I used everything as there, and do not quite understand why it does not work and crashes.
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
int main()
{
int value = 5;
int A_ints[] { 1, 4, 12, 5, 1, 4, 6, 9, 0, 3 };
vector<int> A_vec(value);
vector<int> B_vec { 13, 12, 11, 10 };
vector<int> C_vec;
vector<int> D_vec {9, 6, 5, 4};
partial_sort_copy(A_ints, A_ints + 9, A_vec.begin(), A_vec.end(), greater<int>());
set_difference(A_vec.begin(), A_vec.end(), B_vec.begin(), B_vec.end(), C_vec.begin(), greater<int>());
if (ะก_vec == D_vec)
cout << "Success \n";
else
cout << "Failure \n";
system("pause");
return 0;
}
As a result, if set_difference will works correctly, then the last condition should return "Success".
The 5th argument to set_difference is the parameter that the results of the algorithm will be written to.
You've passed in C_vec.begin() which is an iterator pointing to an empty vector. It's undefined behavior to write to an empty vector's iterator.
You have several issues here, but one solution for this particular problem would be to replace C_vec.begin() with an insert_iterator:
inserter(C_vec, begin(C_vec))
Currently, I've got a program which reads and extracts multiple pieces of data from a file, and i would like to ensure those values correctly match the expected values, I'm aware of how this should work in other programming languages such as python with lists and tuples etc, however i am unsure as to the best approach to use unit tests within C++ whilst keeping the code as minimal and efficient as possible. I've currently got multiple arrays all of which i wish to verify that they meet their expected values, so i can test the program with differing input files.
To describe this, in essence, i wish to verify the contents of e.g.
int arrayone [5] = { 11, 12, 13, 14, 15 };
are equal to
{ 11, 12, 13, 14, 15 }
and to complete the unit test successfully if the values are equal, and to fail if they are not equal or not in the same order. Thus, i am looking for the best method to approach this.
Use a C++ std::array instead and you'll get the benefit from all the methods it exposes, like operator==:
#include <iostream>
#include <array>
int main() {
std::array arrayone{ 11, 12, 13, 14, 15 };
std::array facit{ 11, 12, 13, 14, 15 };
if(arrayone==facit) {
std::cout << "true\n";
} else {
std::cout << "false\n";
}
}
Or for C++11 and C++14:
std::array<int, 5> arrayone{ 11, 12, 13, 14, 15 };
std::array<int, 5> facit{ 11, 12, 13, 14, 15 };
std::mismatch() will get the job done and provides more information than std::equal. This will work with pre-C++11 compilers if you change auto to std::pair<int*, int*>
#include <algorithm>
int expectedResult[5] = {11, 12, 13, 14, 15};
int* arr1end = arrayone + 5;
//I assume here that expectedResult is the same length as arrayone (5).
auto res = std::mismatch(arrayone, arr1end, expectedResult);
if(res.first != arr1end) {
std::cout << "Arrays not matching at " << std::distance(arrayone, res.first) << ", expected: " << *res.second << ", got: " << *res.first;
}
Better version, provided that arrayone is an array type (it could decay to a pointer if you for example pass it as a function argument). It requires C++11 due to usage of auto and std::begin()
#include <algorithm>
#include <iterator>
int expectedResult[5] = {11, 12, 13, 14, 15};
auto res = std::mismatch(std::begin(arrayone), std:end(arrayone), std::begin(expectedResult));
if(res.first != std::end(arrayone)) {
std::cout << "Arrays not matching at " << std::distance(arrayone, res.first) << ", expected: " << *res.second << ", got: " << *res.first;
}
This being said, I recommend you to choose one framework and work with it. These libraries are built explicitly for making unit testing easy and fast (i.e. above sequence is one liner in GoogleTest and is not prone to different array length errors).
I'd also advice you to not use plain C-style arrays. As mentioned by Ted Lyngmo, if you use standard containers you have a lot more options available (e.g. built-in opearator ==) and they also manage resources for you.
If you insist that you must not use the STL and use primitives, this pretty much is a C question since it's not using C++ features. If you can safely assume they'd of size n, the following should be ok.
Given two primitive integer arrays of size n, the general implementation would be
bool equal(int *arr1, int *arr2, int n) {
for (int i = 0; i < n; i++) {
if arr1[i] != arr2[i] return false;
}
return true
}
In general though, std::array would be a better idea than the old C-style arrays, but my understanding of the question is unclear, if you can use the STL then the other solutions are superior.
Edit: In case it's unclear what some problems with the above solution are:
There's no pointer validation
If the arrays are different sizes, this won't work
If you want to validate non-int arrays you'll need another (admittedly) function
(Subjective) the output time is different based on how similar the two arrays are
If you want a bit of a better solution, using memcmp like suggested in the comments (this doesn't use libraries to the best of my knowledge):
For two arrays of type X, and size n, you could simple say
bool eql = !(memcmp(arr1, arr2, n*sizeof(X))
So I got this code sample that needs fixing. From what I can gather it takes an array, reverses it and then counts all the elements within it. Here is the code.
//-------------------------------------------------------------------
void ReverseTheArray( const short *pArrayStart, const int nArrayByteLength )
{
const short *pArrayEnd = (pArrayStart + nArrayByteLength);
while(pArrayStart != pArrayEnd)
{
short tmp = *pArrayStart;
*pArrayStart = *pArrayEnd;
*pArrayEnd = tmp;
pArrayStart++;
pArrayEnd--;
}
}
//-------------------------------------------------------------------
int CountTheArrayContents( const short *pArrayStart, int nNumEntries )
{
assert(nNumEntries-- > 0);
int nCount = 0;
for(unsigned uArrayIndex = nNumEntries; uArrayIndex >= 0; uArrayIndex--)
{
nCount += pArrayStart[uArrayIndex];
}
return nCount;
}
const short g_nSomeNumbers[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
//-------------------------------------------------------------------
int main()
{
short *pDataArray = new short[10];
memcpy(pDataArray, g_nSomeNumbers, sizeof(g_nSomeNumbers));
ReverseTheArray(pDataArray, 10*sizeof(short));
int nCount = CountTheArrayContents(pDataArray, 10);
printf("Sum total is %0.02f\n", nCount);
return 0;
}
I have ideas of what the problems are but can't seem to figure out a simple solution to the problem, one that doesn't require rewriting the entire code. If anyone can read this and see how the errors can be fixed it would be much appreciated.
I'm going to mention some things that I think are causing problems.
All the parameters and the pArrayEnd variable in the ReversTheArray() function are all const but are trying to be changed within the while loop, which is throwing an error. Should the const's be removed? Is there a reason const's would be used for this?
If the const's are remove a runtime error happens when trying to run the for loop in the CountTheArrayContents() function expressing an unhandled exception and saying "Access violation reading location 0x003DFFFE". Drawing a complete blank on that one.
Again any help on the code would be very much appreciated and I couldn't thank you guys enough.
PS. This is a challenge to create a reverse and accumulate function so I'm looking for a fix for the code and not a removal of the two functions. Thank you
PSS. Thanks to everyone who answered. I'm glad I did this (this being the first problem that I've posted about myself) and you've all been a huge help. I've got to say I've learnt alot.
Adding the actual length in bytes will add too many because pointer arithmetic is defined in terms of units of the size of the type pointed to. That is, pArrayEnd becomes &pDataArray[10 * sizeof(short)] instead of &pDataArray[10]. You don't need to multiply by sizeof(short) when calling the reversal function. Alternatively, you can divide nArrayByteLength by sizeof(short) when calculating the initial value of pArrayEnd.
The second issue is the fact that you only have 10 elements (0..9) allocated, meaning &pDataArray[10] would be one element beyond the array. The reversal function then tries to assign data to this unallocated area of memory, which can cause problems. The function should initialize pArrayEnd as shown, but immediately after, it should decrement pArrayEnd by 1. This way you won't be assigning to memory that might not belong to you. Beware of pArrayStart == pArrayEnd before you decrement pArrayEnd. An alternative test would be to ensure nArrayByteLength != 0.
Another problem is if the array has an even number of elements, and you try to do a reversal. If it does have an even number (like 10), pArrayStart will point to pDataArray[4], pArrayEnd will point to pDataArray[5], and after the data is assigned, pArrayStart++ will make pArrayStart point to pDataArray[5] and pArrayEnd-- point to pDataArray[4]. Then (6,3), (7,2), (8,1), (9,0), ... In other words, pArrayStart will never be equal to pArrayEnd in such a case. Instead, you should ensure that pArrayStart < pArrayEnd.
Hope this helps!
Also, any reason for not using std:: reverse? Just wondering.
Edit
The accumulation function can be rewritten as the following, which will avoid the issue with the assert macro while doing the same thing:
int CountTheArrayContents( const short *pArrayStart, int nNumEntries )
{
int count = 0;
assert(nNumEntries);
while (nNumEntries--)
count += pArrayStart[nNumEntries];
return count;
}
Hopefully count doesn't overflow.
If all you're trying to do is reverse the contents of the array and accumulate the result, std::reverse and std::accumulate will do the trick (per the suggestion by #chris). Here's an example, which maintains the dynamically allocated short*. A better solution would use std::vector or std::array.
#include <algorithm>
#include <numeric>
#include <stdio.h>
#include <memory.h>
const short g_nSomeNumbers[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
int main()
{
short *pDataArray = new short[10];
memcpy(pDataArray, g_nSomeNumbers, sizeof(g_nSomeNumbers));
std::reverse(pDataArray, pDataArray+10);
int nCount = std::accumulate(pDataArray, pDataArray+10, 0);
for( size_t i=0; i<10; ++i )
printf("%d ", pDataArray[i]);
printf("\n");
printf("Sum total is %d\n", nCount);
delete [] pDataArray;
return 0;
}
This prints
9 8 7 6 5 4 3 2 1 0
Sum total is 45
Why does the loop below not set the pinMode to OUTPUT for the pins in the array pins[]?
int pins[21];
void setup() {
int pins[] = {13,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
for (int i = 0; i < sizeof(pins); i++) {
pinMode(pins[i], OUTPUT);
}
}
To get it to work, I have to set them manually:
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
// ...
Wrong breaking condition causes Undefined behaviour due to n index-out-of bound problem :
for (int i = 0; i < sizeof(pins); i++)
^-----------^
should be:
for (int i = 0; i < sizeof(pins)/sizeof(pins[0]); i++)
^---------------------------^
Note: When you apply the sizeof operator to an array type, the result is the total number of bytes in the array.
To understand formula read: Weird behavior when printing array in C?
Change sizeof(pins) to sizeof pins / sizeof *pins.
sizeof yields the size of the array in bytes and not the number of elements of the array.
For starters, sizeof(pins) will be sizeof(int) times the number of entries in pins. Accessing values outside the range causes undefined behavior. You probably meant to use
sizeof(pins)/sizeof(pins[0])
or in C++ just size(pins) with a suitable function template like
template <typename T, std::size_t Size>
constexpr std::size_t size(T(&)[Size]) { return Size; }
Why the functions don't work can't be seen from the code snippet you provided as the code doesn't include the definition of the functions (or macros) pinMode().
Although you can use sizeof(array)/sizeof(array[0]) or a template to compute the size of the array (or, equivalently, use it to find the end of the array), if you're using a reasonably current compiler, it already knows how to handle the job correctly on its own:
for (auto i : pins)
pinMode(i, OUTPUT);
At least in my opinion, this seems like the simplest of the three.
I am try to make the myFunction give me a sum of the values in the array, but I know I can not use a return value, and when I run my program with the code as so all I get is a print out of the values and no sum why is that?
void myFunction (int i) {
int total = 0;
total += i;
cout << total;
}
int main() {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for_each( array, array+10, myFunction);
return 0;
}
You really need a functor to store state between iterations:
struct Sum
{
Sum(int& v): value(v) {}
void operator()(int data) const { value += data;}
int& value;
};
int main()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int total = 0;
std::for_each( array, array+10, Sum(total));
std::cout << total << std::endl;
}
When you declare a variable (i.e. int total) it exists for the duration of its scope (usually equivalent to the nearest surrounding pair of { and }. So, in your function myFunction, total ceases to exist when the function returns. It returns once per call--once per element in your array, that is. In order to actually sum its values (or otherwise preserve a variable beyond the end of myFunction, you must give it a broader scope.
There are two relevant ways to do this. One is a "good" way, and one is an "easier-but-badly-styled" way. The good way involves a functor or context object--#Martin has already posted an example. The "bad" way is marking int total as static. It'll work the first time you use it, if your code is single-threaded... and then never again. If somebody suggests it... don't do it. :)
total is a variable with automatic storage duration. Every time myFunction() is called, a new total is created and initialized to 0. You could:
give total static storage duration (with the static keyword), but you won't be able to assign its value to anything, because it is still local scope. A bad idea if you want to reuse this function, anyhow.
make total a global variable. Also a bad idea if you want to reuse this function
make a "functor", as described in Martin York's answer. This is the most reusable implementation
But, my chosen solution is "you're asking the wrong question" and you should be using std::accumulate():
#include <iostream>
#include <numeric>
int main() {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int total = std::accumulate(array, array+10, 0);
std::cout << total << '\n';
return 0;
}
Your total is local at each function call. It's initialized with 0 at every iteration. You could just declare it global (or pack into a parameter, etc.)
myFunction is being called each time and total is local to the function... try marking total as static instead:
static int total = 0
You need to make the total persistent across function calls. You also need to access the result separately from adding the intermediate results to it, which rules out (at least straightforward use of) a function at all -- you really need a class instead.
The total is a local variable. It will be destroyed once the myFunction finished processing one data.
The typical way to have a state is to make myFunction a function object (a struct that overloads the () operator).
The dirty way is to make total a global variable.
In your case I'd recommend you use the accumulate function instead (assuming that cout << total is just for debugging).
You reset the value of 'total' to 0 each time you call the function.
Declare it 'static'
void myFunction (int i) {
static int total = 0;
total += i;
cout << total;
}
EDIT:
Alternatively, if you want to access the value of 'total' later, you will need to either use a global variable (of some kind! Could be in a class or functor! don't flame me!), or just use a for loop, and pass it in as a pointer (i.e., not use for_each):
void myFunction (int i, int * p_total) {
//No initialization
*p_total += i;
cout << *p_total;
}
int main() {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int total = 0;
for(int i = 0; i < 10, i++)
myFunction(array[i], &total);
//total is now 55
return 0;
}
Note: I'm a C programmer trying to learn C++. This is how I would do it (which is very C-like), it might not be the standard C++ way.