Внутренний поток в C

#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 значений. Так что, если он создаст an int[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 — Я не вижу в вопросе ничего, что говорило бы о том, что они пытаются избежать двойного анализа, просто они вообще не знают, как это сделать.