#c #arrays #stream #byte #int
#c #массивы #поток #байт #int
Вопрос:
Я реализую функцию на C, где я преобразую байт [] в int[] . Проблема в том, что длина int[] зависит от содержимого byte[] (а не только от длины byte[] ), поэтому я не буду знать общую длину int[], пока не повторю весь байт[] . Поэтому я ищу какую-либо форму av int-stream или динамически увеличивающийся int-list, в который я могу записать, а затем преобразовать в int[], как только я закончу писать все целые числа. На данный момент мой опыт работы с C немного ограничен, поэтому я не совсем уверен, что считается лучшей практикой для решения такого рода проблем. Есть предложения?
Комментарии:
1. С помощью C вы можете выражать эти конструкции так, как считаете нужным. Является ли это преимуществом или недостатком, зависит от вашей точки зрения.
2. Знаете ли вы размер
byte[]
до достижения конца?3. @stevehb — нет, он не знает размер
int[]
перед оценкойbyte[]
.4. Однопроходное решение потребует перераспределения, что с большей вероятностью приведет к сбою по мере роста вашего массива. Конечно, это маловероятно, если вы не выполняете какую-то серьезную обработку…
Ответ №1:
Самым простым методом было бы выделить элемент int[]
той же длины (количества элементов), byte[]
что и , и когда вы закончите и узнаете размер, вызовите realloc
его, чтобы уменьшить.
Это предполагает, конечно, что при интерпретации данных никогда не будет создано больше целых чисел, чем байтов в потоке.
Комментарии:
1. Из вопроса: «итак, я не буду знать общую длину int[], пока не повторю весь байт []».
2. @steve: смысл в том, чтобы выбрать случайный размер, который гарантированно будет больше, чем вам нужно (чтобы он не переполнялся), а затем уменьшить его до нужного размера, когда вы закончите.
3. @Chris — согласен — но это не то, что сказал плакат. Он сказал «быть одинаковой длины»
4. @Steve: Да, он не знает общей длины
int[]
. Я предполагаю, что он знает общую длинуbyte[]
, и что еслиbyte[]
содержит N значений, в финалеint[]
не будет больше N значений. Так что, если он создаст anint[N]
, он в безопасности и может впоследствии изменить его размер.
Ответ №2:
Я могу придумать несколько способов сделать это.
Исходя из вашего вопроса, я предполагаю, что преобразование вашего char[]
в соответствующий int[]
s является дорогостоящим (именно поэтому вы хотите избежать выполнения этого вычисления дважды — один раз для определения размера и снова для заполнения содержимого.
Итак, вот как я бы это сделал:
Во-первых, существует ли максимальный размер, который вы можете связать с преобразованием? ПРИМЕР: существует ли максимальная разница в размере 2 к 1? (Для каждого символа в char[] может ли он создавать целые числа «до X»?)
Если это так, и использование памяти не является проблемой (вы не сильно ограничены) — продолжайте и выделите максимальный размер, заполните его по мере выполнения перевода и перераспределите, когда закончите, чтобы уменьшить объем памяти.
Если это не так, вы находитесь в более сложных условиях и должны искать несмежные схемы, такие как связанный список. После того, как вы выполнили перевод и создали свой связанный список, вы можете выделить место для своего массива и посетить каждый элемент в связанном списке, чтобы заполнить массив.
Ответ №3:
Сначала проверьте byte[], чтобы определить результирующий размер int[] . Затем используйте malloc()
для выделения структуры int[] соответствующего размера.
#include <stdlib.h>
...
// imagine that the resulting int[] size depends on the sum of the bytes
int j, size = 0;
for (j = 0; byte[j]; j)
size = byte[j];
int *int_array = (int *) malloc (size);
for (j = 0; j < size; j)
int_array [j] = whatever;
Комментарии:
1. Я понимаю его вопрос в том, что он специально стремится избежать этого двойного анализа, который вы предлагаете.
2. @Steve: Хотя один проход может показаться более чистым, описание «кажется», что двухпроходное решение — это верное убийство.
3. Вы предполагаете, что преобразование элементов в byte[] в соответствующие им элементы int[] является «дешевым». Возможно, каждый из них включает в себя вычисление числа Pi до миллиона знаков после запятой… дело в том, что я не думаю, что OP задавал бы вопрос так, как он есть, если бы преобразование было дешевым.
4. @BrendanLong — я делаю только одно предположение — что преобразование достаточно дорого, чтобы он не хотел делать это дважды. И вы не упомянули третий вариант — несмежную схему хранения, например, связанный список.
Ответ №4:
Во-первых, если вы можете использовать C , то вы можете просто использовать a vector
, который представляет собой массив динамического размера. В противном случае вам придется сначала выполнить итерацию по вашему массиву байтов, чтобы определить, каким должен быть размер массива int, а затем динамически выделить массив int. Во-вторых, C не имеет byte
типа, поэтому обычно используется тип char
.
#include <stdlib.h>
char byte_array[ size ];
int i, int_size = 0;
int *int_array;
for ( i = 0; i < size; i ) {
int_size = f( byte_array[i] );
}
int_array = (int*) malloc( int_size );
где f()
какая-то функция, которую вы пишете, которая просматривает один элемент массива байтов, чтобы помочь определить, насколько большим должен быть массив int.
Комментарии:
1. Как и решение wallyk, это также страдает от проблемы двойного анализа, которую, похоже, пытается избежать OP.
2. @Steve — Я не вижу в вопросе ничего, что говорило бы о том, что они пытаются избежать двойного анализа, просто они вообще не знают, как это сделать.