Removing trailing zeros in an array - c++

I am trying to create a program that doesn't print the trailing zeros in an array.
My array size is 23. I am trying to start from the 23rd position in a for loop and end the for loop once a one is reached. Then I would only print up to that position. I have can't seem to get it right though. Can someone help me with this?
Thanks
void removeTrailZero(int array[]) {
int i = 0;
for (i = 23; array[i] == 0; i--) {
// printf("%d", i);
}
for (int x = 1; x < i + 1; x++) {
printf("%d",array[x]);
}
}

You can do something like this
for (i = 22; i >= 0; --i)
{
if (array[i] != 0)
break;
}
Then print your array between 0 and i (included)

Right now, your code looks like C, not C++. At least assuming the tag is correct and you really want to write C++ rather than C, I'd consider using some of the algorithms in the standard library to handle at least part of the job.
The standard library has an std::find_if to use for finding the value you care about. This works with iterators, not directly with the underlying storage. Since you want to start searching from the end, you can use a reverse_iterator to find the correct point:
auto last = std::find_if(std::crbegin(array), std::crend(array),
[](auto i) { return i != 0; });
When we print out the data, we want to iterate forward through the array from the beginning to that point--but that's a reverse_iterator, so we need to call its base() to get a forward iterator, and give that as the end of the range we want to print:
std::copy(std::cbegin(array), last.base(),
std::ostream_iterator<int>(std::cout, "\n"));

If You compile with C++14 -std=c++14 you can use the answer's #JerryCoffin:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>
template <std::size_t SIZE>
void removeTrailZero(const std::array<int, SIZE>& array) {
auto last = std::find_if(std::crbegin(array), std::crend(array),
[](auto i) { return i != 0; });
std::copy(std::cbegin(array), last.base(),
std::ostream_iterator<int>(std::cout, " "));
}
int main() {
std::array<int, 23> array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0};
removeTrailZero(array1);
std::cout << std::endl;
std::array<int, 15> array2 = {1, 2, 3, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0};
removeTrailZero(array2);
std::cout << std::endl;
}
Output:
❯❯❯ g++ -std=c++14 ../test.cc -o test && ./test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 0 0 4 5 6
For compiling with C++11 -std=c++11 you can use:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <string>
template <std::size_t SIZE>
void removeTrailZero(const std::array<int, SIZE>& array) {
auto last = std::find_if(array.crbegin(), array.crend(),
[](int i) { return i != 0; });
std::copy(array.cbegin(), last.base(),
std::ostream_iterator<int>(std::cout, " "));
}
int main() {
std::array<int, 23> array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0};
removeTrailZero(array1);
std::cout << std::endl;
std::array<int, 15> array2 = {1, 2, 3, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0};
removeTrailZero(array2);
std::cout << std::endl;
}
Output:
❯❯❯ g++ -std=c++11 ../test.cc -o test && ./test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 0 0 4 5 6
For older version of C++11, you can use:
#include <iostream>
void removeTrailZero(int array[]) {
int i = 22;
for (; i >= 0 && array[i] == 0; --i);
for (int j = 0; j <= i; ++j) {
std::cout << array[j] << " ";
}
}
int main() {
int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0};
removeTrailZero(array);
std::cout << std::endl;
int array2[] = {1, 2, 3, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
removeTrailZero(array2);
std::cout << std::endl;
}
Output:
❯❯❯ g++ ../test.cc -o test && ./test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 0 0 4 5 6
Note: For C++11 and C++14, removeTrailZero is a template function and can receive diferent sizes of std::array. For older version of C++11 removeTrailZerois design for receive a int[23].

Related

Array value as a condition

I have an array of integers called test containing 7 elements,I want to write an if statement to check if the 6 first values of the array are equal to a certain collection of values,what I tried was:
if (test == {1, 0, 1, 0, 0, 0} ) {
//statement(s)
}
However,the line containing the condition gives me an "expected an expression error",what am I doing wrong?
Thanks in advance.
C++17 versions using deduction guides:
std::array
std::array test{1, 0, 1, 0, 0, 0};
if(test == std::array{1, 0, 1, 0, 0, 0}) {
std::cout << "equal\n";
}
std::vector
std::vector test{1, 0, 1, 0, 0, 0};
if(test == std::vector{1, 0, 1, 0, 0, 0}) {
std::cout << "equal\n";
}
If you use std::array you can simply rely on operator==
std::array<int, 7> a1 = {1, 2, 3, 4, 5, 6, 7};
std::array<int, 7> a2 = {2, 3, 4, 5, 6, 7, 8};
std::cout << "a1 == a1 " << (a1 == a1) << std::endl;
std::cout << "a1 == a2 " << (a1 == a2) << std::endl;
However, if for some reason you need to use C-style array, then you can use std::memcmp, which will compare the arrays byte by byte:
int ca1[7] = {1, 2, 3, 4, 5, 6, 7};
int ca2[7] = {2, 3, 4, 5, 6, 7, 8};
std::cout << "ca1 == ca1 " << (std::memcmp(ca1, ca1, sizeof(ca1)) == 0) << std::endl;
std::cout << "ca1 == ca2 " << (std::memcmp(ca1, ca2, sizeof(ca1)) == 0) << std::endl;
Note that you need to compare the std::memcmpy result with 0, which means that they are equal. reference However, in this approach you should first check if the dimensions are equal.
Here is a way to do it (if your test is an std::array):
#include <algorithm>
...
std::vector<int> v({1, 0, 1, 0, 0, 0});
if( (v.size()==test.size()) && std::equal(test.begin(), test.end(), v.begin()) ) {
// statement(s)
}
or
#include <algorithm>
...
std::vector<int> v({1, 0, 1, 0, 0, 0});
if( std::equal(test.begin(), test.end(), v.begin(), v.end()) ) {
// statement(s)
}

Why is this dynamic array implementation slower than std::vector<T>?

Bellow is a simple template array implementation using malloc and realloc
Stepping through with a debugger, there were less code steps than vector.
However, when timing using std::chrono, std::vector is still faster.
Why is this?
(Compiling using gnu cc v9)
#include <../array.hpp>
#include <../console.hpp>
#include <vector>
int main() {
console::time("array");
array<int> a { 1, 2, 3, 4, 5, 6, 7 };
console::timeEnd("array");
for (unsigned int i = 0; i < a.size(); i++) {
console::log(std::to_string(a[i]));
}
array<int> b { 1, 2, 3, 4, 5, 6, 8 };
if (a != b) {
console::log("a != b");
}
array<int> c { 1, 2, 3, 4, 5, 6, 7 };
if (a == c) {
console::log("a == c");
}
console::time("std::vector");
vector<int> v { 1, 2, 3, 4, 5, 6, 7 };
console::timeEnd("std::vector");
for (unsigned int i = 0; i < v.size(); i++) {
console::log(std::to_string(v[i]));
}
return 0;
};
array: 27µs - timer ended
1
2
3
4
5
6
7
a != b
a == c
std::vector: 2655ns - timer ended
1
2
3
4
5
6
7
Full implementation [here](https://gist.github.com/universefullofthings/ac933d64158217478a02df7bdcc8f319?.

How to make Kronecker product of two random vectors of vectors?

I need to make a function which takes two parameters (two vectors of vectors) and as a result returns a vector of vectors which is a Kronecker product of two given vectors of vectors.
Whatever I do, my new vector of vectors is created by the same number (the one which should be only on the last position). For example if I have vector of vectors A: {3, -1},{0, 5} and B:{4,3,15},{0, -5, 2} my Kronecker product will be: {10, 10, 10, 10, 10, 10}, {10, 10, 10, 10, 10, 10} etc, instead of {12, 9, 45, -4, -3, -15}, {0, -15, 6, 0, 5, -2}, {0, 0, 0, 20, 15, 75}, {0, 0, 0, 0, -25, 10}
Matrix KroneckersProduct(Matrix A, Matrix B){
Matrix mat=CreateMatrix(NoRows(A)*NoRows(B),NoCols(A)*NoCols(B));
for(int i=0;i<NoRows(A)*NoRows(B);i++){
for(int j=0;j<NoCols(A)*NoCols(B);j++){
for(int k=0;k<NoRows(A);k++){
for(int l=0;l<NoRows(B);l++){
for(int m=0;m<NoCols(A);m++){
for(int n=0;n<NoCols(B);n++){
mat.at(i).at(j)=A.at(k).at(m)*B.at(l).at(n);
}
}
}
}
}
}
return mat;
}
This is the algorithm for Kronecker product. Maybe I switched v1 and v2
#include <vector>
#include <iostream>
using Matrix = std::vector<std::vector<double>>;
Matrix KroneckersProduct(Matrix v1, Matrix v2){
Matrix v(v1.size() * v2.size(), std::vector<double>(v1[0].size() * v2[0].size()));
for (std::size_t z1(0); z1 < v1.size(); ++z1) {
for (std::size_t z2(0); z2 < v2.size(); ++z2) {
for (std::size_t z3(0); z3 < v1[0].size(); ++z3) {
for (std::size_t z4(0); z4 < v2[0].size(); ++z4) {
v[z1*v2.size() + z2][z3*v2[0].size() + z4] = v1[z1][z3] * v2[z2][z4];
}
}
}
}
return v;
}
int main() {
Matrix v1{{3, -1},{0, 5}};
Matrix v2{{4,3,15}, {0, -5, 2}};
Matrix v(KroneckersProduct(v1, v2));
for (const auto& row : v) {
for (const auto& cell : row) {
std::cout << cell << " ";
}
std::cout << '\n';
}
return 0;
}
Output:
12 9 45 -4 -3 -15
0 -15 6 -0 5 -2
0 0 0 20 15 75
0 -0 0 0 -25 10

Sorting 2D Vector Array Based On a Column

I have a 2d vector array which contains :
row id r b main
1 0 26 3
2 1 11 2
3 1 46 4
4 2 26 1
5 3 11 2
I want to sort every row based on its "main"-column value
smaller "main"-column.
smaller value => the entire row should be on the top.
if there is tow rows or more and there "main"-column have the same value, I want to check "r"-column.
smaller value => the entire row should be on the top.
after sorting it will look like this:
row id r b main
4 2 26 1
2 1 11 2
5 3 11 2
1 0 26 3
3 1 46 4
Try using std::sort like
using int_arr = std::array<int, 4>;
std::sort(std::begin(arr), std::end(arr), [](const int_arr& a, const int_arr& b){
return a[3] != b[3] ? a[3] < b[3] : a[1] < b[1];
});
Demo
#include <iostream>
#include <array>
#include <algorithm>
int main() {
using int_arr = std::array<int, 4>;
int_arr arr[5] = {
{1, 0, 26, 3},
{2, 1, 11, 2},
{3, 1, 46, 4},
{4, 2, 26, 1},
{5, 3, 11, 2}
};
for(const auto& i_arr : arr) {
for(const auto& i : i_arr)
std::cout<< i <<", ";
std::cout << "\n";
}
std::cout << "**************\n";
std::sort(std::begin(arr), std::end(arr), [](const int_arr& a, const int_arr& b){
return a[3] != b[3] ? a[3] < b[3] : a[1] < b[1];
});
for(const auto& i_arr : arr) {
for(const auto& i : i_arr)
std::cout<< i <<", ";
std::cout << "\n";
}
}
OutPut
1, 0, 26, 3,
2, 1, 11, 2,
3, 1, 46, 4,
4, 2, 26, 1,
5, 3, 11, 2,
**************
4, 2, 26, 1,
2, 1, 11, 2,
5, 3, 11, 2,
1, 0, 26, 3,
3, 1, 46, 4,

Storing input file into a 2d array C++

I have an input file that I would like to use by using cin.
My input file contains a list of 9x9 numbers, such as:
1 2 3 4 5 6 7 8 9
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 ...
6 ...
7 ...
8 ...
9 ...
I want to store these values into a 2d array, so they would look like:
int board[9][9] = {{1, 2, 3, 4, 5, 6, 7, 8, 9},
{2, 2, 3, 4, 5, 6, 7, 8, 9},
{3, 2, 3, 4, 5, 6, 7, 8, 9},
{4, 2, 3, 4, 5, 6, 7, 8, 9},
{5, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 3, 4, 5, 6, 7, 8, 9},
{7, 2, 3, 4, 5, 6, 7, 8, 9},
{8, 2, 3, 4, 5, 6, 7, 8, 9},
{9, 2, 3, 4, 5, 6, 7, 8, 9}};
I tried to do:
int board[9][9];
for (int i=0;i<9;i++) {
for (int j=0;j<9;j++) {
std::cin >> board[i][j];
}
}
However, I don't think it's working. I'm going to use them as inputs when I run my code.
This works for me in GCC 4.9.0 with C++11:
Sample Code:
#include <iostream>
int main() {
int board[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
std::cin >> board[i][j];
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
std::cout << board[i][j];
}
std::cout << std::endl;
}
return 0;
}
You should change C array for std::vector or other container from STL, it provide a lot of benefice (automatic memory management, array bound check, etc...). If you could use C++11, the new range for loop is a big improvement too (syntactical and performance wise, it avoid error as off by one, incorrect bounds, etc...).
Here is a C++11 version:
#include <iostream>
#include <vector>
int main() {
typedef std::vector<int> row_t;
typedef std::vector<row_t> board_t;
board_t board(9, row_t(9));
for (auto& row : board) {
for (auto& cell : row) {
std::cin >> cell;
}
}
for (const auto& row : board) {
for (auto cell : row) {
std::cout << cell;
}
std::cout << std::endl;
}
return 0;
}
The inner loop is wrong, there you have j++ as the loop condition. And as in the first iteration j will be zero (which in C++ is the same as false) the loop will not iterate at all. Besides, the inner loop is missing a semicolon, so it shouldn't even compile.