В базе ответа NGLG https://stackoverflow.com/a/8811242/6619626 вы можете использовать следующую функцию:
type
OurArrayStr=array of string;
function SplitString(DelimeterChars:char;Str:string):OurArrayStr;
var
seg: TStringList;
i:integer;
ret:OurArrayStr;
begin
seg := TStringList.Create;
ExtractStrings([DelimeterChars],[], PChar(Str), seg);
for i:=0 to seg.Count-1 do
begin
SetLength(ret,length(ret)+1);
ret[length(ret)-1]:=seg.Strings[i];
end;
SplitString:=ret;
seg.Free;
end;
Он работает во всех Delphi версии.
Чтобы немного расширить это, помните, что массивы C ++ - это в точности массивы C. Таким образом, все, что у вас есть, это адрес фрагмента памяти, который якобы (без каких-либо гарантий) является массивом чего-то.
Хорошо, мы расширим немного больше.
C (и, следовательно, C ++) на самом деле не имеет «массивов» как таковых. Все это есть адреса, указатели. Поэтому, когда вы создаете что-то «массив», в действительности вы говорите компилятору, что некоторая переменная представляет адрес.
Полезно проводить различие в C между объявлением и определение . В объявлении вы просто даете что-то имя и тип; в определении вы фактически выделяете пространство.
Итак, если мы начнем с определения массива, подобного
int ar[100];
, это означает, что мы сообщаем компилятору, что нам нужно пространство для 100 int
, мы хотим, чтобы он был размещен в одном фрагменте, и мы собираюсь использовать имя ar
для него. Оператор sizeof
дает число байтов, используемых типом или объектом, поэтому наш массив ar
займет 100 × sizeof (int)
байтов. На большинстве машин это будет 400 байт, но оно варьируется от машины к машине.
Если мы определяем переменную
int * ar_p; // using '_p' as a reminder this is a pointer
, мы определяем пространство для переменной, которая будет содержать адрес. Его размер будет sizeof (int *)
, который обычно будет 4 или 8, но на некоторых машинах может быть от 2 до 16 на некоторых машинах, с которыми вы вряд ли столкнетесь в ближайшее время.
Имя массива: ar
. Компилятор преобразует это имя в адрес, поэтому мы можем сохранить этот адрес с помощью
ar_p = ar ; // THIS WORKS
Теперь, скажем для удобства, наш массив ar
, как оказалось, начинался с местоположения 1000 в памяти.
Это имя ar
не не имеет места для него; это как константа, число. Таким образом, вы не можете отменить это назначение
ar = ar_p ; // THIS WON'T WORK
по той же причине, по которой вы не могли сказать
1000 = ar_p ; // THIS WON'T WORK EITHER
, т. Е. Вы не можете изменить значение 1000. (Назад в ранних версиях FORTRAN этот трюк работал бы, для сложные причины. Это была ошибка. Вы никогда не жили, пока не попытались отладить программу, в которой значение «2» равно 3.)
Массивы в C всегда начинаются с нуля, то есть Первый индекс всегда равен нулю. Любые другие индексы - это просто адреса, вычисленные с использованием индекса. Таким образом, ar [0]
- это просто адрес 1000 плюс 0 байтов смещения или 1000. ar [1]
равен 1000 плюс 1 раз размер int
, поэтому следующий int закончен. И на самом деле, это всегда верно в C.
Это называется ссылкой на массив .
Когда мы используем синтаксис * ar_p
, мы сообщаем компилятору получить вещь по адресу, указанному в ar_p
. `.
Это называется разыменованием указателя .
Если мы говорим
ar_p = ar;
, то * ar_p
и ar [0]
относятся к одному и тому же ,
Когда мы говорим ar [0]
, мы говорим компилятору, что мы хотим получить объект по адресу 0 байтов из ar
. ar [1]
- это адрес один int
или 4 байта из ar
. Так, * (ar_p + 3)
относится к тому же, что и ar [3]
. (Нам нужны круглые скобки, потому что мы хотим сначала добавить 3 к адресу, а затем посмотреть содержимое. * ar_p + 3
получит содержимое, на которое указывает сначала ap_p
, а затем добавьте к ним 3.
Дело в том, что Си не знает или не очень заботится о том, насколько велик массив в действительности. Если я приду и сделаю ar [365]
, компилятор с радостью сгенерируйте код для просмотра в ячейке 1000+ (365 × sizeof (int)
). Если это в вашем массиве, хорошо, но если это просто случайная память, это тоже хорошо. C все равно.
(Помните, C приходит из телефонной компании. «Нам все равно; нам не нужно. Мы» (t + i)
будет равняться адресу в t
плюс i * sizeof (TYPE)
Объяснено это также выше. Когда вы индексируете в массив, например, ar [42]
, это означает, что вы хотите получить 42-е число вне начального адреса. Итак, если вы используете int
, то вам нужно переместиться в 42 раза, как бы ни было шире int
, то есть sizeof (int)
.
Теперь, это все C, и, поскольку C ++ определен как «вид» C, это также относится и к C ++. ЗА ИСКЛЮЧЕНИЕМ
TYPE
не определен пользователем, который перегружает операторы []
и оператор *
. в C ++, вы можете решить, что хотите Определите новый тип, который действует так же, как и любой другой тип, но вы можете изменить способ, которым язык делает определенные вещи. Так, программист может решить «перегрузить», т. е. заменить - поведение по умолчанию операторов массива и разыменования указателя на что-то свое. Как новичок, вы не должны столкнуться с этим в ближайшее время, но вы должны знать об этом.
Вы не должны использовать sizeof (originalarray) / sizeof (int)
таким образом. Это будет работать только для статически объявленных массивов (размер известен во время компиляции). Вы должны передать размер вместе с ним. Почему бы вам просто не сделать вектор
из массива и вместо этого передать его?
Примечание для стороны: Как правило, всегда помните, что sizeof
будет быть переведенным во время компиляции. Так что он никак не мог узнать размер массива, переданного в качестве аргумента.
Я вижу, вы включаете <вектор>
. Я предлагаю вам покончить со всеми видами использования массивов и использовать только класс vector
. Вы можете увидеть примеры того, как использовать контейнеры STL, такие как vector
здесь .
Когда вы передаете массивы функциям, они распадаются на указатели на первый элемент массива, несмотря на запись. Итак, ваш sizeof
не работает должным образом.
Когда вы передаете массив, лучше всего передать размер массива, чтобы вы знали, где остановиться. Добавьте его в качестве дополнительного параметра.
В дополнение ко всем ответам выше, вы также можете проверить вопросы и ответы по массивам из c-faq. com: http://c-faq.com/aryptr/index.html
К сожалению, очень сложно делать именно то, что вы хотите, на C или C ++. Вы можете передать массив фиксированного размера следующим образом:
int mergeSort(int originalarray[20])
{
// do something
}
Однако размер вашего массива не определяется числом, он определяется количеством элементов в списке инициализации.
В вашем случае (хотя на самом деле это неправильно) нужно сделать это в два этапа:
int originalarray[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
const size_t arraySize = sizeof originalarray / sizeof originalarray[0];
int mergeSort(int array[arraySize])
{
// do something
}
Жаль, что он не сделает то, что вам нужно: передать массив такой функции, как это создает копию массива, и целью сортировки будет изменение исходного массива.
По правде говоря, вы не можете пойти дальше без понимания концепции «указателя».
Функция, которую вам нужно разработать, действительно должна быть такой:
int originalarray[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
const size_t arraySize = sizeof originalarray / sizeof originalarray[0];
int mergeSort(int *array, const size_t size)
{
// do something
}
mergeSort(&(originalArray[0]), arraySize);
Другими словами, вы передаете указатель на первый элемент и количество элементов.
В качестве альтернативы вы можете иметь дело с векторами. Вектор инкапсулирует те же две вещи (указатель на первый элемент и размер) в единую сущность, называемую «объектом». Кроме того, он управляет памятью за вас, поэтому вы можете увеличивать количество элементов по мере необходимости. Это способ C ++. Жаль, что вы не можете инициализировать вектор с помощью {...}, как массив.
Looks like you're using both dynamically allocated arrays and vectors, when I believe just using std::vector will be enough.
First, let your input array be changed to a std::vector, and fill it with your input data.
int main()
{
std::vector<int> originalarray;
for (int data = 1; data <= 10; data++)
{
originalarray.push_back(data);
}
mergeSort(originaldata);
}
Now it's important to declare your mergesort function to take a reference to a std::vector.
int mergeSort(std::vector<int>& originalarray)
{
// The rest of your code, note that now you are passing
// in your array for sorting, so you can continue with your code to split
// the vector into farray and sarray
// then call sort on your halves.
mergeSort(farray);
mergeSort(sarray);
// I'm guessing at this point you'd write code to combine your farray sarray, and
// put it back into originalarray...don't forget to clear original array first!
}
Just a note, looks like you're not doing an inplace sort, so expect your sort to take a while since you're copying out a lot of data.