вернуть строку, содержащую миллиард символов - PullRequest
0 голосов
/ 29 марта 2012

Привет, у меня есть функция, которая принимает целое число n и возвращает строку, содержащую числа от 1 до n, разделенные ','.Теперь это число целое число n может быть любым числом до 1 миллиарда.Что может быть лучшим решением для этого.И как мне справиться с проблемами, связанными с памятью, например, если объем оперативной памяти составляет всего 2 Гб, что будет, если я верну эту большую строку в C #.Сигнатура функции:

string convtostr (int n)
{}

, поэтому вход для eg может быть n = 5, тогда на выходе будет строка типа «1,2,3,4,5»

Ответы [ 4 ]

2 голосов
/ 29 марта 2012

Полагаю, лучшее решение для вас - вообще не использовать эту строку :) Вы можете заключить эту строку в класс, содержащий только число n:

class LargeStringWithNumbers
{
  int upper_bound;
  public void Print()
  {
    for (int j = 0; j < upper_bound; j++ )
    {
      System.Console.Write("{0};", j);
    }
    System.Console.Write("\n");
  }
}

Она будет вести себя так же, как есливы содержали строку все время, кроме вас.

2 голосов
/ 29 марта 2012

Вы не можете создать такую ​​большую строку в .NET.2 ГБ - это максимальный размер объекта, независимо от того, сколько у вас памяти.

Вместо того, чтобы возвращать строку, вы можете предоставить объект, который позволяет вам перебирать символы в результате, но вычисляет их толькоспрос.

0 голосов
/ 29 марта 2012

Давайте посмотрим на предел дизайна:

n = 1 миллиард:

когда n равно одному миллиарду, запятые "," сами по себе съедают ваше доступное пространство, так как char === 2 байта; так что 2 байта * 1 миллиард = 2 ГБ - 2 байта (на самом деле у вас 2 миллиарда - 1 запятая). Следовательно, из этого базового наблюдения идея должна заключаться в том, чтобы сжать результат до 2 ГБ. Строка - это объект, размер которого ограничен 2 ГБ.

Поэтому вопрос в том, как вы кодируете сообщения между объектами? Т.е. один объект вызовет функцию с n и ожидает сообщения от вызываемого объекта. Обратите внимание, что вас попросили напечатать результат, а не возвращать строку. Если подпись функции, которую вы представляете, на самом деле написана интервьюером на доске (в отличие от вашей интерпретации вопроса), то ответ от suddnly_me не сработает, иначе это ваш ответ.

Предполагая, что подпись - это то, что написал интервьюер, как вы отправляете сжатое сообщение между двумя объектами? Как бы шутко это не звучало, я бы вернул n в виде строки.

 string convtostr (int n)
 {
  return n+"";
 }

Затем, в зависимости от того, для чего будет использоваться возвращаемое значение, я напишу декодеры / парсеры для декодирования сообщения. Например, если при вызове необходимо записать строку в файл, то метод / функция записи будет преобразовывать строку обратно в int и выполнять итерацию от 1 до n во время записи в файл.

Я продержался достаточно долго. Вы поняли идею.

0 голосов
/ 29 марта 2012

Если след вашего метода должен точно соответствовать тому, что вы показываете, то это невозможно сделать. Потому что вы не можете наследовать String и создавать новый лучший тип, который будет работать для> 2GB

Если ваше предположение о максимальном входном значении n неверно, то вы можете предоставить рабочее решение, соответствующее площади. Например, максимальное значение n было 10000 или что-то очень маленькое.

Однако я думаю, что подход IEnumerable<char>, предложенный @MikeSamuel, является единственным ответом, который представит работающее решение, возвращающееся близко к заявленным требованиям.

Поскольку вы отметили это c# 4.0 Скорее всего, они искали решение, которое использовало бы синтаксис yield, такой как:

static IEnumerable convtostr(int n)
{
    for (int i = 1; i < n; i++)
        yield return string.Format("{0}, ", i.ToString());
    yield return n.ToString();
}

затем вы можете объяснить, что вы используете его следующим образом

int input = 1000000000; // 1 billion.

foreach (var value in convtostr(input))
{
    Console.Write(value );
}

И, вероятно, они хотели, чтобы вы ответили. Поскольку это будет работать с очень небольшим количеством активной памяти, фактически не сохраняя всю последнюю строку в памяти.

Редактировать: еще один ответ, аналогичный предложенному @suddnely_me, - вместо этого передать действие для каждого числа, например:

static void convtostr(int n, Action<int> action)
{
    for (int i = 1; i <= n; i++)
        action(i);
}

Затем вызывается с помощью:

int input = 1000000000; // 1 billion.
convtostr(input, n =>
    {
        if (n < input) { Console.Write("{0}, ", n); }
        else { Console.Write(n); }
    });

Что на самом деле будет работать почти так же, как при использовании синтаксиса yield.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...