Compare and merge vector elements C++ - c++

I have a (somewhat) basic question. I have a vector with string elements of the following type:
1 X 2
1 X 4
1 X 7
2 Y 1
2 Y 3
3 X 4
3 X 12
.....
etc
Now what I want to do is to merge the elements that have the same starting coefficient and append "00" until I have 6 integer elements after X,Y etc so my output would be:
1 X 2 4 7 00 00 00
2 Y 1 3 00 00 00 00
3 X 4 12 00 00 00 00
.....
I've tried iterating over my vector and comparing my elements with find() and adding them to another vector but it doesn't work. I'm not super comfortable with vectors so any ideas would be appreciated! :)

Related

regex in python to remove 2 patterns

Want to make a regex to remove 2019 and 0 from left side of the string and last six zeroes from right side of the string.
original value Dtype : class 'str'
original value: 2019 01 10 00 00 00
expected output is : 1 10
Using str.split with list slicing.
Ex:
s = "2019 01 10 00 00 00"
print(" ".join(s.split()[1:3]).lstrip("0"))
Using re.match
Ex:
import re
s = "2019 01 10 00 00 00"
m = re.match(r"\d{4}\b\s(?P<value>\d{2}\b\s\d{2}\b)", s)
if m:
print(m.group("value").lstrip("0"))
Output:
1 10

Why isn't memset assigning 1? [duplicate]

This question already has answers here:
Why is memset() incorrectly initializing int?
(9 answers)
Closed 6 years ago.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int color[1001][1001];
int main() {
int i, j;
memset(color, 1, sizeof(color[0][0]) * 2 * 2);
for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++) {
printf("%d ", color[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
output:
16843009 16843009 16843009 16843009
0 0 0 0
0 0 0 0
0 0 0 0
Why isn't it assigning 1? Why didn't it print 1 instead of 16843009 ? How can i assign integer 1?
But if i write memset(color, 0, sizeof(color[0][0]) * 2 * 2); Then the output:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
Why is this?
Any answer will be highly appreciated. Thanks in advance.
Because memset sets each byte to 1.
So if int is four bytes (32 bits, what it most commonly is) then you set each element to 0x01010101.
Read more in this memset reference page.
For a more C++-ish solution I suggest using std::fill:
std::fill(&color[0][0], &color[0][0] + sizeof(color) / sizeof(color[0][0]), 1);
That will set all elements to 1.
A third option is to use std::array instead, and its fill member function:
std::array<std::array<int, 1001>, 1001> color;
...
for (auto& inner : color)
{
inner.fill(1);
}
Manpage :
#include <string.h>
void *memset(void *s, int c, size_t n)
The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
Therefore, memset can't be used to initialize int array with 1 because if int is represented by 4 bytes, then it will initialize each bytes with 1.
16843009 is equivalent to 0x01010101. Each of 4 bytes are initialized with 01.
Using memset, an array of int can only be initialised with 0 or -1 because 0 and -1 both have all bits 0 and 1 respectively in two's complement binary representation regardless of the size of int data type.
memset() will write the specified value to every byte in the range, so if int is 4-byte long, the value will be 0x01010101, not 1.
To assign integer 1, assign integer 1.
for (i = 0; i < (int)(sizeof(color)/sizeof(*color)); i++) {
for (j = 0; j < (int)(sizeof(color[i])/sizeof(*color[i])); j++) {
color[i][j] = 1;
}
}
memset() is setting your memory 8-Bit aligned to the value you chose, which is 1. But for your array color[][] you declared the 32-Bit datatype int, which has four bytes. So what memset() does is to set each of this four bytes to the value 1.
This also explains your result: 16843009d = 0x01010101.
If you have a look at your memory:
memset() to 1:
//.color[0][0].||..color[0][1]...||..color[0][2]...||..color[0][3]..
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
//.color[1][0].||..color[1][1]...||..color[1][2]...||..color[1][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
//.color[2][0].||..color[2][1]...||..color[2][2]...||..color[2][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
//.color[3][0].||..color[3][1]...||..color[3][2]...||..color[3][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
memset() to 0:
//.color[0][0].||..color[0][1]...||..color[0][2]...||..color[0][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
//.color[1][0].||..color[1][1]...||..color[1][2]...||..color[1][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
//.color[2][0].||..color[2][1]...||..color[2][2]...||..color[2][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
//.color[3][0].||..color[3][1]...||..color[3][2]...||..color[3][3]..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
If you are calling memset() with the value 0 then you get a 32 Bit int value = 0x00000000 = 0d.
Note:
If you want to set your whole array to a value use the following line:
memset(color, 1, sizeof(color));
Then your array looks the following:
1010101 1010101 1010101 1010101
1010101 1010101 1010101 1010101
1010101 1010101 1010101 1010101
1010101 1010101 1010101 1010101
View the code here[^].

Creating Diagonals in SAS

I am trying to convert my columns to diagonals using SAS.
For example
D C1 C2 C3 C4 C5
J 11 00 14 15 20
F 00 13 16 00 30
M 00 00 18 19 00
A 00 00 00 98 50
S 00 00 00 00 41
Want this converted to
D N1 N2 N3 N4 N5
J 11 00 14 15 20
F 13 16 00 30
M 18 19 00
A 98 50
M 41
Can anyone tell or help me with this?
Update base on new info: This just uses an array to shift the values starting from the diagonal to the left. Not dependent of on values in the lower triangle.
data havethis;
infile cards firstobs=2;
input D:$1. C1-C5;
cards;
D C1 C2 C3 C4 C5
J 11 00 14 15 20
F 00 13 16 00 30
M 00 00 18 19 00
A 00 00 00 98 50
S 00 00 00 00 41
;;;;
run;
data want;
set havethis;
array c[*] c:;
array N[&sysnobs];
j = 0;
do i = _n_ to dim(c);
j + 1;
n[j] = c[i];
end;
drop j i;
run;
This method use two transposes (flip/flop), it assumes only zeros are on the off diagonal (better if they were missing) and missing is what you get as result. I like this method because you don't have to know anything, like how many.
data havethis;
input D:$1. C1 C2 C3;
format c: z2.;
cards;
J 11 12 14
M 00 13 15
A 00 00 16
;;;;
run;
proc transpose data=havethis out=wantthis(drop=_name_ where=(col1 ne 0));
by D notsorted;
run;
proc transpose data=wantthis out=whatthismore(drop=_name_) prefix=N;
by d notsorted;
run;

memory structure of a vector<T>

I am playing around with vectors in c++ and I've tried to figure out how a vector looks inside memory...
I made a vector like this: vector<int> numbers = { 1, 2, 3, 4, 5, 6 }; and extracted a couple of information about the vector
&numbers: 002EF8B8
begin()._Ptr: 0031A538
end()._Ptr: 0031A550
data at vector memory location 002EF8B8 :
00 9d 31 00 38 a5 31 00 50 a5 31 00 50 a5 31 00
cc cc cc cc 30 31 82 1f
found begin()._Ptr and end()._Ptr addresses stored there...
and integers found in that address range:
1st int at memory location: 0031A538 = 01 00 00 00
2nd int at memory location: 0031A53C = 02 00 00 00
3rd int at memory location: 0031A540 = 03 00 00 00
4th int at memory location: 0031A544 = 04 00 00 00
5th int at memory location: 0031A548 = 05 00 00 00
6th int at memory location: 0031A54C = 06 00 00 00
Question:
If 002EF8B8 is the memory location of the vector, 31 00 38 a5 and 31 00 50 a5 are beginning and the end of vector, what is 00 9d at the beginning and the data after? 31 00 50 a5 31 00 cc cc cc cc 30 31 82 1f
I got the size with numbers.size()*sizeof(int) but I'm almost sure that's not the actual size of vector in memory.
Can someone explain to me how can I get the size of actual vector, and what does each part of it represent?
something like:
data size [2 bytes] [4 bytes] [4 bytes] [? bytes]
data meaning [something] [begin] [end] [something else]
EDIT:
bcrist suggested the use of /d1reportAllClassLayout and it generated this output
1> class ?$_Vector_val#U?$_Simple_types#H#std## size(16):
1> +---
1> | +--- (base class _Container_base12)
1> 0 | | _Myproxy
1> | +---
1> 4 | _Myfirst
1> 8 | _Mylast
1> 12 | _Myend
1> +---
which is basically [_Myproxy] [_Myfirst] [_Mylast] [_Myend]
You misinterpret the bytes. On a little-endian machine, the value 0x0031A538 is represented with the sequence of bytes 38 A5 31 00. So, your highlights are shifted.
Actually you have four addresses here: 0x00319D00, 0x0031A538, 0x0031A550 and again 0x0031A550.
A vector minimally needs three values to control its data, one of them being, obviously, the vector base. The other two may be either pointers to the end of vector and the end of allocated area, or sizes.
0x0031A538 is obviously the vector base, 0x0031A550 is both its end and the end of allocated area. What still needs explanation, then, is the value 0x00319D00.

Binary File interpretation

I am reading in a binary file (in c++). And the header is something like this (printed in hexadecimal)
43 27 41 1A 00 00 00 00 23 00 00 00 00 00 00 00 04 63 68 72 31 FFFFFFB4 01 00 00 04 63 68 72 32 FFFFFFEE FFFFFFB7
when printed out using:
std::cout << hex << (int)mem[c];
Is there an efficient way to store 23 which is the 9th byte(?) into an integer without using stringstream? Or is stringstream the best way?
Something like
int n= mem[8]
I want to store 23 in n not 35.
You did store 23 in n. You only see 35 because you are outputting it with a routine that converts it to decimal for display. If you could look at the binary data inside the computer, you would see that it is in fact a hex 23.
You will get the same result as if you did:
int n=0x23;
(What you might think you want is impossible. What number should be stored in n for 1E? The only corresponding number is 31, which is what you are getting.)
Do you mean you want to treat the value as binary-coded decimal? In that case, you could convert it using something like:
unsigned char bcd = mem[8];
unsigned char ones = bcd % 16;
unsigned char tens = bcd / 16;
if (ones > 9 || tens > 9) {
// handle error
}
int n = 10*tens + ones;