Bitwise integer concationation - c++

For some background, I'm trying to write a system to pass packets of integers for the purpose of building a maze using a boolean toggle to decide whether two nodes should have a wall between them, currently my maze handles 480 walls, therefore I don't want to send a packet with a single item, but rather split it into an array of integers (length 8) thus giving me 480/8 objects to send.
const int wallRows = mazeSize / 8;
int temp = NULL;
int temp2 = NULL;
int current = NULL;
int concatCount = 0;
int* walls = new int[wallRows];
int wallIndex = 0;
for (int i = 0; i < mazeSize; i++) {
current = temp2;
//ensure my ints have only 8 bytes
if (concatCount >= 7) {
//allocate a full int to the array
walls[wallIndex] = temp;
//clear the int
temp = NULL;
//move to the next array pos
wallIndex++;
//restart the int count
concatCount = 0;
}
if (maze->allEdges[i]._iswall) {
//append a 1 to the int
temp = 0b1;
}
else {
//append a 0 to the int
temp = 0b0;
}
//increment the int count
current = (temp2 << 1) | temp;
concatCount++;
}
This is what I have currently built, my idea was to start with an int, pass it the int based on the return of the bool "_isWall" and bit shift the result onto the end of the int.
When the int reaches capacity, iterate to the next int in the array and begin again until the maze's walls have populated the array.
Edit: lack of clarity on what I was asking.
My bitwise operation does not appear to actually allocate multiple bits to the same integer, where am I going wrong?

Use val | (1UL << temp2), and not temp2 << 1 to set the bits. Later you can use bitwise & operator to see if the bit is set. You must initialize the whole byte to zero and set the bit only if the value is true. Here is an example:
int main(void)
{
//assign random values for testing
int wallinfo[480];
for(int i = 0; i < 480; i++)
wallinfo[i] = !!(rand() % 2);
//copy to the values to compress
unsigned char compress[60] = { 0 };
for(int i = 0; i < 60; i++)
for(int j = 0; j < 8; j++)
if(wallinfo[i * 8 + j])
compress[i] |= 1UL << j;
//decompress to get back wallinfo
int decompress[480];
for(int i = 0; i < 60; i++)
for(int j = 0; j < 8; j++)
decompress[i * 8 + j] = !!(compress[i] & (1UL << j));
//wallinfo should match decompress
if(memcmp(wallinfo, decompress, 480) == 0)
printf("success\n");
else
printf("failed\n");
return 0;
}

Related

Why The Elements of 2 Identical arrays Equal each other

I should mention the purpose of this code is to tackle a leading zero scenario when finding date palindromes in dates in format MMDDYYY.
Here is the code.
#include <iostream>
using namespace std;
unsigned numDigits (unsigned num)//this works
{
if (num < 10) return 1;
return 1+ numDigits(num/10);
}
int main ()
{
unsigned date = 1111110;//01/11/1110(jan 11th of 1110 is palindrome)
cout<<numDigits(date)<<"num of dig"<<endl;
if (numDigits(date) == 7)
{
unsigned array[8];
unsigned number = date;
unsigned revArr[8];
for (int h = 7; h >= 0; h--) //this pops array withdate
{
array[h] = number % 10;
number /= 10;
cout<<array[h]<<endl;
}
cout<<"vs"<<endl;
for (int i = 0; i < 8; i++) //this pops revarray withdate
{
revArr[i] = number % 10;
number /= 10;
cout<<array[i]<<endl;
}
for (int j = 0; j < 8; j++)
{
if (array[j] == revArr[j])
{
cout<<j<<"th digit are" <<" equal"<<endl;
}
}
}
return 0;
}
In this case both of the arrays are identical, I don't underdtdanwd why array[0] == revArr[0] but array[1] != revArr[1] and so on but array[7] == revArr[7] again... its boggling my mind.
The loops traverse all elements of the array. Even when the expression number /= 10 is equal to 0. In this case the zero is stored in the array elements because 0 / 10 gives again 0.
Before the second loop write
number = date;

Print the same array, it is different in different functions, why?

I'm writing a program to solve the shortest path between two points in a circuit wiring. I use the BFS(breadth search first) method. I save the path in the path array, but I find that the coordinates of the last point in the path are not what I want (sometimes the value is correct and sometimes not).So, I printed out the path array in the findPath function, which was correct, but not correct in the main function.Why?
What's wrong with my description?I am not a native English speaker and my English is not particularly good.Please point out if what I said is not clear.
English retrieval ability is still poor, I do not know if this problem is repeated.If repeated please forgive me!
Thank you very much!
#include<iostream>
#include <iomanip>
#include<queue>
using namespace std;
const int M = 9;
const int MAXLEN = 30;
class Point
{
public:
int x;
int y;
};
//The increments in the x and y direction,
// in the order of up, right, down, and left
int dx[4] = {0,1,0,-1};
int dy[4] = {-1,0,1,0};
void findPath(int G[][M],Point start,Point finish,int& pathLen,Point path[])
{
//Find the shortest path from start to finish and its length, pathLen
if(start.x == finish.x && start.y == finish.y) //Two overlapping
{
pathLen = 0;
return ;
}
Point cur,next;
G[start.x][start.y] = 1; //Start of blockade
queue<int> qx,qy; //Coordinates the queue
qx.push(start.x); qy.push(start.y); //The starting point enters the queue
while(!qx.empty())
{
cur.x = qx.front(); qx.pop(); // 'cur' stands for current position
cur.y = qy.front(); qy.pop();
for(int i = 0;i < 4; i++)
{
next.x = cur.x + dx[i]; next.y = cur.y + dy[i]; // next is the next position
if(!G[next.x][next.y]) //The location is not marked
{
G[next.x][next.y] = G[cur.x][cur.y] + 1;
if(next.x == finish.x && next.y == finish.y) //Finish line
{
break;
}
qx.push(next.x);
qy.push(next.y);
}
}
if(next.x == finish.x && next.y == finish.y) break; //Finish line
}
//Structural path
pathLen = G[finish.x][finish.y];
cur = finish;
for(int i = pathLen-1; i >= 0; i--)
{
path[i] = cur; //Record current position
for(int j = 0; j < 4; j++) //Look for the previous position
{
next.x = cur.x + dx[j];
next.y = cur.y + dy[j];
if(G[next.x][next.y] > -1 && G[next.x][next.y] < G[cur.x][cur.y])
{
break;
}
}
cout<<"path["<<i<<"]="<<path[i].x<<","<<path[i].y<<endl;
cur = next; //Move to current position
}
}
int main()
{
int G[M][M]; //Grid map
Point start,finish; // The starting point and end point
int pathLen; //Shortest path length
for(int i = 0; i < M; i++) //Initializes the outer fence as -1
{
G[0][i] = G[M-1][i] = G[i][0] = G[i][M-1] = -1;
}
for(int i = 1; i < M-1; i++) //Initialize the region in the grid to 0
{
for(int j = 1; j < M-1; j++)
G[i][j] = 0;
}
G[5][1] = -1; G[6][1] = -1; G[6][2] = -1; G[6][3] = -1; G[7][1] = -1;
G[7][2] = -1; G[7][3] = -1; G[1][3] = -1; G[2][3] = -1; G[2][4] = -1;
G[3][5] = -1; G[4][4] = -1; G[4][5] = -1; G[5][5] = -1; // Inside a wall
for(int i = 0; i < M; i++) //Initial time map
{
for(int j = 0; j < M; j++)
{
cout<<setw(4)<<G[i][j];
}
cout<<endl;
}
start.x = 3; start.y = 2; finish.x = 4; finish.y = 6;
Point *path = new Point[M];
findPath(G,start,finish,pathLen,path);
for(int i = 0; i < M; i++) //Complete time map
{
for(int j = 0; j < M; j++)
{
cout<<setw(4)<<G[i][j];
}
cout<<endl;
}
for(int i = 0; i < pathLen; i++)
{
cout<<"path["<<i<<"]="<<path[i].x<<","<<path[i].y<<endl;
}
return 0;
}
output:
As you can see in the figure below, the path[9] output in the findPath function is different from that in the main function.
Sometimes the results are right
Valgrind says:
==27791== Invalid read of size 4
==27791== at 0x401B7B: main (delme.cpp:113)
==27791== Address 0x4daf108 is 0 bytes after a block of size 72 alloc'd
==27791== at 0x4839593: operator new[](unsigned long) (vg_replace_malloc.c:433)
==27791== by 0x401A03: main (delme.cpp:101)
==27791==
==27791== Invalid read of size 4
==27791== at 0x401BA6: main (delme.cpp:113)
==27791== Address 0x4daf10c is 4 bytes after a block of size 72 alloc'd
==27791== at 0x4839593: operator new[](unsigned long) (vg_replace_malloc.c:433)
==27791== by 0x401A03: main (delme.cpp:101)
you are accessing erroneous bytes (outside your allocated memory)
the line reported by valgrind is
cout<<"path["<<i<<"]="<<path[i].x<<","<<path[i].y<<endl;

Truncating an array of char via function C++

trying to format this function as it will truncate an array of char (anything that the user enters it will split that up to a number the user also enters)
void truncate(char array[], int maxLength)
{
// Variable definition
int x = 0;
// While loop start.
while (array[x] <= maxLength)
{
cout << array[x];
x++;
}
}
The array parameter in the function header is just a string that was entered by the user, its an array of char. And the maxLength parameter is an int variable entered by the user as well, it could be 3, 4 or 5. The maxLength is supposed to act as the null termination whatever the user enters the string will truncate after that number.
But this code doesn't work, it doesn't display an output for the function. Anyone know what I'm doing wrong? Thanks.
The problem here is this:
while (array[x] <= maxLength)
This is comparing the character returned from the array at x to the value of maxLength, so you're comparing a char to an int. I would recommend the more standard for loop for this:
for (int x = 0; x < maxLength; x++) {
cout << array[x];
}
int truncate(const char *str, int maxchunk, char ***chunks)
{
int len = strlen(str);
int nchunks = len / maxchunk + !!(len % maxchunk);
char **table = malloc(sizeof(char *) * (nchunks));
if (table != NULL)
{
for (int i = 0; i < nchunks; i++)
{
if ((table[i] = malloc(sizeof(char) * maxchunk + 1)) == NULL)
{
for (int j = i - 1; j >= 0; j--)
{
free(table[j]);
}
free(table);
table = NULL;
break;
}
strncpy(table[i], str + i * maxchunk, maxchunk);
*(table[i] + maxchunk) = '\0';
}
}
*chunks = table;
return table == NULL ? -1 : nchunks;
}

I'm trying to build a min-heap array from another array of frequencies

i'm trying to build a min-heap in an array from an array where the index corresponds to an ASCII value and the value at that index represents a frequency.
I then use these find min functions to retrieve the minimum value
int findMinIndex(int *x){
int a = findMaxValue(x);
int i = 0;
int index;
for(i = 0;i < 128;i++){
if(a > x[i] && x[i] != 0){
a = x[i];
index = i;
}
}
return index;
}
int findMinValue(int *x){
int a = findMaxValue(x);
int i = 0;
for(i = 0;i < 128;i++){
if(a > x[i] && x[i] != 0){
a = x[i];
x[i] = 0;
}
}
return a;
}
After i retrieve those two values, i attempt to enter them into an array of heap objects
class node{
public:
int occurances;
char val;
};
for some reason when i do this, it only seems to fill the array partially correctly then fills the rest with the max frequency repeatedly.
when i use cout to see the array i end up with this
heap[1] = 1
heap[2] = 2
heap[3] = 6
heap[4] = 8
heap[0] = 36
heap[0] = 36
heap[0] = 36
heap[0] = 36
i can't really figure out what this means, or why this is happening.
so how can i fix it to where i end up with a min heap in array form?

How to efficiently manuplate very long vector?

I have a very long vector as below in Eigen:
MatrixXi iIndex(1000000);
which is initialized into zeros, with only a short continuous part(less than 100) filled with 1 's, the position of which is randomized.
I need to do the following things in a long loop:
int count;
int position;
for(int i=0;i<99999;i++){
//... randomly fill iIndex will short `1` s
// e.g. index = (someVectorXi.array() == i).cast<int>();
count = iIndex.sum(); // count all the nonzero elements
//position the first nonzero element index:
for (int j=0; j<1000000;j++){
if(iIndex(j))
position = j;
}
}
But it is really very slow.
Is there any way to expedite?
my 2 cents: group the bits in e.g. uint32_t, so you can check whether an i32 differs from 0. When it is different, then you may take longer to find out which bits are 1.
Assuming the number of bits is a multitude of 32 (making it easier):
for (int i = 0; i < max / sizeof(uint32_t); ++i)
{
if (wordGrp[i] != 0)
{
uint32_t grp = wordGrp[i];
for (j = 0; j < BITS_PER_UINT32; j++)
{
if ((grp & 1) == 1) std::cout << "idx " << (i*32 + j) << " is 1\n";
grp >>= 1;
}
}
}