Хотя этот популярный ответ даст вам желаемый синтаксис индексации, он вдвойне неэффективен: большой и медленный как в пространстве, так и во времени.
Почему этот ответ большой и медленный
Предлагаемое решение состоит в создании динамического массива указателей, а затем инициализации каждого указателя на собственный независимый динамический массив. Преимущество этого подхода состоит в том, что он дает вам синтаксис индексации, к которому вы привыкли, поэтому, если вы хотите найти значение матрицы в позиции x, y, вы скажете:
int val = matrix[ x ][ y ];
работает, потому что матрица [x] возвращает указатель на массив, который затем индексируется с помощью [y]. Разрушение:
int* row = matrix[ x ];
int val = row[ y ];
Удобно, да? Нам нравится наш синтаксис [x] [y].
Но решение имеет большой недостаток, который заключается в том, что он как жирный, так и медленный.
Почему?
Причина, по которой это как жир, так и медленный, на самом деле то же самое. Каждая «строка» в матрице представляет собой отдельно распределенный динамический массив. Создание распределения кучи является дорогостоящим как во времени, так и в пространстве. Распределитель занимает время, чтобы сделать выделение, иногда выполняя алгоритмы O (n), чтобы сделать это. И распределитель «прокладывает» каждый из ваших массивов строк с дополнительными байтами для бухгалтерии и выравнивания. Это дополнительное пространство стоит ... ну ... дополнительное пространство. Освобождение будет также взять дополнительное время, когда вы идете на освобождение матрицы, тщательно освобождая каждое выделение каждой строки. Получает меня в поту, просто думая об этом.
Есть еще одна причина, по которой это медленно. Эти отдельные распределения, как правило, живут в прерывистых частях памяти. Одна строка может быть по адресу 1000, другая по адресу 100 000 - вы получите эту идею. Это означает, что когда вы проходите матрицу, вы прыгаете через память, как дикий человек. Это, как правило, приводит к промахам в кеше, которые значительно замедляют время обработки.
Итак, если вы абсолютный должен иметь свой симпатичный синтаксис [x] [y], используйте это решение. Если вы хотите быстроту и малость (и если вам все равно, почему вы работаете на C ++?), Вам нужно другое решение.
Другое решение
Лучшее решение состоит в том, чтобы выделить всю вашу матрицу в виде единого динамического массива, а затем использовать (слегка) умную математическую индексацию для доступа к ячейкам. Матрица индексирования только немного умна; nah, это не умно: это очевидно.
class Matrix
{
...
size_t index( int x, int y ) const { return x + m_width * y; }
};
Учитывая эту функцию index()
(которую я представляю, является членом класса, потому что он должен знать m_width
вашего матрица), вы можете получить доступ к ячейкам в матричном массиве. Матричный массив выделяется следующим образом:
array = new int[ width * height ];
Таким образом, эквивалент этого в медленном, жирном решении:
array[ x ][ y ]
... это в быстрой, малой Решение:
array[ index( x, y )]
Грустный, я знаю. Но вы привыкнете к этому. И ваш процессор поблагодарит вас.
Решение состоит в том, чтобы использовать свойство TempData для хранения желаемых компонентов Запроса.
, Например:
public ActionResult Send()
{
TempData["form"] = Request.Form;
return this.RedirectToAction(a => a.Form());
}
Затем в Вашем действии "Формы" можно пойти:
public ActionResult Form()
{
/* Declare viewData etc. */
if (TempData["form"] != null)
{
/* Cast TempData["form"] to
System.Collections.Specialized.NameValueCollection
and use it */
}
return View("Form", viewData);
}
Следует иметь в виду, что TempData хранит набор формы на сессии. Если Вам не нравится то поведение, можно реализовать новый интерфейс ITempDataProvider и использовать некоторый другой механизм для того, чтобы хранить временные данные. Я не сделал бы этого, если Вы не знаете для факта (через измерение и представляющий), что использование Состояния сеанса причиняет Вам боль.
Существует иначе, который избегает tempdata. Шаблон, который я люблю, включает создание 1 действия и для исходного рендеринга и для перерендеринга недопустимой формы. Это проходит примерно так:
var form = new FooForm();
if (request.UrlReferrer == request.Url)
{
// Fill form with previous request's data
}
if (Request.IsPost())
{
if (!form.IsValid)
{
ViewData["ValidationErrors"] = ...
} else {
// update model
model.something = foo.something;
// handoff to post update action
return RedirectToAction("ModelUpdated", ... etc);
}
}
// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();
Это - шаблон более или менее. Немного pseudoy. С этим можно создать 1 представление для обработки рендеринга формы, восстановления изображения значений (так как форма будет заполнена предыдущими значениями), и показывающий сообщения об ошибках.
, Когда регистрация на это действие, если его допустимое это передает управление другому действию.
я пытаюсь сделать этот шаблон легким в платформа проверки .NET , поскольку мы пристраиваем поддержку MVC.
Смотрите на MVCContrib, можно сделать это:
using MvcContrib.Filters;
[ModelStateToTempData]
public class MyController : Controller {
//
...
}