kasper
Гость
|
|
« : 19-11-2005 23:39 » |
|
У нас есть два массива. Нужно выяснить, имеются ли в них одинаковые элементы. Скажите чо-нибудь умное, пожалуйста! Мой собственный код этой проги получается большой! И еще: размер массивов не лигитимирован! То есть в них может быть разное колличество элементов!
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #1 : 19-11-2005 23:44 » |
|
Сортировать массивы можно?
Если нет, то можно ли сделать их копию, которую потом отсортировать?
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #2 : 19-11-2005 23:51 » |
|
можно сортировать, можно использовать указатели и ссылки, размещать в динамич. памяти, можно делать копию
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #3 : 20-11-2005 00:00 » |
|
Ну если можно, тогда алгоритм простой.
1. Сортируем массивы по возрастанию. 2. Делаем текущими первые элементы обоих массивов. 3. Пока не конец массива, цикл: 3.1. Сравнить текущие элементы первого и второго массива. 3.2. Если равны, то нашел одинаковые; оба текущие эл-та продвинуть на 1 и продолжать цикл. 3.1. Иначе если текущий эл-т первого массива меньше текущего эл-та второго массива, то продвинуть тек. эл-т первого, иначе продвинуть тек. эл-т второго массива и продолжать цикл.
Поскольку оба массива отсортированы по возрастанию, нужно каждый раз продвигаться на шаг по тому массиву, текущий элемент которого меньше. Тогда за один проход соберешь все совпадения.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #4 : 20-11-2005 00:14 » |
|
Это получается: о1------а1 о2------а2 о3------а3 о4------а4, а мне надо: о1-----а1, а2, а3, а4 о2-----а1, а2, а3, а4 о3-----а1, а2, а3, а4 о4-----а1, а2, а3, а4
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #5 : 20-11-2005 00:20 » |
|
Это чего такое значит? Я такого не понимаю. Где тут два массива?
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #6 : 20-11-2005 00:24 » |
|
a o
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #7 : 20-11-2005 00:34 » |
|
Ну так сортируешь оба и сравниваешь, начиная с первого элемента. А потом тот массив, у которого текущий меньше, продвигаешь на 1 и так далее.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #8 : 20-11-2005 00:38 » |
|
Пробовал, не хочет компилировать! Сразу же говорит об ошибках. Таких, что дальнейшее использование работающей проги невозможно. Приходиться закрывать окно и мучиться дальше
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #9 : 20-11-2005 00:48 » |
|
Так алгоритм и не будет компилироваться. Его сначала в программу на С++ превратить нужно, и желательно без ошибок.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #10 : 20-11-2005 00:51 » |
|
)) так дело в том, что не могу пока описать сей алгоритм! знаний синтаксиса не хватает. Делаю как могу, прога получается очень большой! Я хотел спросить, как сделать по-короче
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #11 : 20-11-2005 00:58 » |
|
Ну и спросил бы, что именно не получается.
Сортировка - несложная штука, хорошо в литературе описана. Мой алгоритм тоже сложным не назовешь. Не должна программа большой получиться. Покажи, что именно вызывает затруднения.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #12 : 20-11-2005 01:06 » |
|
Смысл в том, что я могу сделать так: for(int i=0; i<10; i++) { if(o==a[i+1]) cout<<o; } Как сделать так, чтобы не пришлось 10 раз писать это же? И что делать если размер массива вводится с консоли, и разный?
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #13 : 20-11-2005 01:15 » |
|
Немного не так. Примерно вот так нужно: for (int acurr=0, ocurr=0; acurr<amax && ocurr<omax;) { if (a[acurr] == o[ocurr]) { твои действия в случае совпадения элементов; acurr++; ocurr++; } else if (a[acurr] < o[ocurr]) acurr++; else ocurr++; }
Вроде так, если ничего наспех не пропустил.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #14 : 20-11-2005 01:20 » |
|
Aif, спасибо, я завтра прокомплю. Сейчас голова не варит. Около 36 часов бодрствую. Щас кусну чно-нибудь и спать лягу.
|
|
|
Записан
|
|
|
|
Alex437
Гость
|
|
« Ответ #15 : 22-11-2005 15:20 » |
|
А std нельзя юзать? А то бы совсем красиво было: vector<int> a, o; vector<int>::const_iterator it; for(unsigned i = 0; i < a.size(); ++i) { it = find(o.begin(), o.end(), a[i]); if(it != o.end()) { cout << *it; } }
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #16 : 22-11-2005 18:52 » |
|
Может, конечно, и можно. Однако по моим прикидкам алгоритм получается порядка N2 действий (при размерности массивов порядка N), а это не так уж красиво при больших N. Хотя код и получается короче на пару строчек, но эта экономия дорого обойдется в итоге.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #17 : 24-11-2005 22:30 » |
|
Вот так как я это думаю: #include<iostream.h>
int main() { int a[11]={10, 20, 30, 40 ,50 ,60 ,70 ,80 ,90, 100, 0}; int b[11]={15, 25, 35, 45, 55, 65, 75, 85, 95, 105, 0}; int counter=0; do{for(int i=0; i<10; i++) if(a[counter]==b[i]) cout<<"b["<<i<<"]="<<b[i]<<endl; if(b[i]=='\0') counter++; }while(a[counter]!='\0'); counter=0; do{for(int i=0; i<10; i++) if(b[counter]==a[i]) cout<<"a["<<i<<"]="<<a[i]<<endl; if(a[i]=='\0') counter++; }while(b[counter]!='\0');
return 0; }
|
|
« Последнее редактирование: 20-12-2007 17:07 от Алексей1153++ »
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #18 : 24-11-2005 22:31 » |
|
Попробуйте поставить одинаковые цифры в маасивах
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #19 : 01-12-2005 17:11 » |
|
Может, конечно, и можно. Однако по моим прикидкам алгоритм получается порядка N2 действий (при размерности массивов порядка N), а это не так уж красиво при больших N. Хотя код и получается короче на пару строчек, но эта экономия дорого обойдется в итоге.
Зато не требует предварительной сортировки обоих массивов. Если сравнивать однопроходный алгоритм вместе с сортировкой vs то, что Alex437 изобразил... Если я правильно помню оценку qsort, то получается n*m против n*ln(n)+m*ln(m)+max(m,n). А вот искать при каких m и n одно лучше другого мне сейчас лениво.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Alf
Гость
|
|
« Ответ #20 : 01-12-2005 23:01 » |
|
... Если я правильно помню оценку qsort, то получается n*m против n*ln(n)+m*ln(m)+max(m,n). А вот искать при каких m и n одно лучше другого мне сейчас лениво. А там за нас уже все давно нашли. Правда, ворочать кирпичи Кнута ради такой мелочи неохота, а более попсовые "Жемчужины программирования" Бентли оставил на работе. Однако помню, что результаты измерений Бентли на реальных задачах поражают воображение цифрами. Конечно, на десятке-сотне элементов ничего не заметишь, все за один тик таймера пролетит. А на настоящих задачах может получиться весьма зримо. Аналогичный пример. Одиниз моих сотрудников сводил баланс нашего обмена трафиком с партнерами, кто кому сколько должен. Расчеты длились более суток, причем сервер с данными находится в удаленной сети, которая порой глюкает, и необходимо либо перезапускать задачу, либо делать откат. Я решил поглядеть, что это за суперзадача, которая на мощном компе делается так долго (мне подозрительно все, что крутится дольше нескольких минут на компе с миллиардом операций в секунду, ибо помню времена, когда мечтали о миллионе). В результате оказалось, что подходящий тариф для направления каждый раз ищется в массиве линейным поиском(!). Заставил товарища разбить массив на несколько частей, каждую отсортировать (что далось бесплатно, ибо исходные данные все равно берутся с SQL-сервера) и заменить линейный поиск двоичным, то есть вместо (t ~ N/2) поиск стал производиться за (t ~ log 2(N/10)). В численном выражении это составило ~40 сек вместо прежних ~35 часов. Раньше парень запускал задачу и присматривал, не случилось ли чего по ходу. Теперь он, пардон, по нужде не успеет выскочить за время ее выполнения, нажал - получи результат. Как говорится, "думайте сами, решайте сами" (С). Мораль: не заигрывайте с алгоритмами порядка N 2, они не столь безобидны, как кажутся с виду. И не экономьте несколько строчек несложного кода, в конечном итоге боком выйдет.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #21 : 02-12-2005 00:02 » |
|
Есть еще интересная задачка, я ее уже написал. Помучайтесь пока: В линейку вбиты гвозди, находящиеся на заданных расстояниях p1, p2,…,pN друг от друга. Соседние гвозди можно связывать нитками. Не должно остаться ни к кому не привязанных гвоздей. Нужно найти способ их связывания, обеспечивающий минимум суммарной длины нитей.
|
|
|
Записан
|
|
|
|
Михалыч
|
|
« Ответ #22 : 02-12-2005 02:21 » |
|
Если условие описано дословно и корректно то мне кажется все элементарно. Но это если понимать описанную задачу ДОСЛОВНО. Гвозди вбиты "в линейку" - стало быть по прямой линии. Расстояния между гвоздями м.б. не одинаковым - сие и не важно. Но кратчайшее расстояние между двумя точками до сих пор была прямая линия. Стало быть и ответ сам по себе напрашивается - связывай гвозди последовательно друг за другом. И будет тебе кратчайшая нитка. Другое дело, что это явно не так, уж больно все просто. Мне кажется, что явная неоднозначность прочтения и понимания условия задачи "зарыты" вот тут - "ни к кому не привязанных гвоздей". Уточните задачу, иначе ее решать можно исходя только из собственных предположений - см. первое решение. В нем тоже не осталось "не привязанных" гвоздей. Вопрос только КАК не привязанных
|
|
|
Записан
|
Поживем - увидим... Доживем - узнаем... Выживу - учту
|
|
|
Alf
Гость
|
|
« Ответ #23 : 02-12-2005 10:40 » |
|
Есть еще интересная задачка, я ее уже написал. За какое время твоя программа обсчитывает сотню гвоздей?
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #24 : 03-12-2005 21:06 » |
|
Закон такой: если в задаче есть неточности, и что то непонятно, то делай так как понял. Мое решение: #include<iostream.h> #include<stdlib.h> #include<conio.h> #include<iomanip.h>
int main() { int sum, odd=1, even=0, pass, zero=1, counter=0, hold; int array[10]; cout<<endl<<"* Enter coordinate nail (santimetre): "<<endl; sum=0; cout<<" "; for(int i=0; i<10; i++) {array[i]=rand() % 99 + 1;} for(pass=0; pass<10; pass++) for(i=0; i<10; i++) if(array[i]>array[i+1]) {hold=array[i]; array[i]=array[i+1]; array[i+1]=hold;} for(i=0; i<10; i++) {cout<<array[i]<<setw(3); counter++; if(counter==2) {cout<<" "; counter=0;} }do{sum=sum+((array[odd])-(array[even])); odd=odd+2; even=even+2; }while(even<10); cout<<endl<<" For ligament only nearby nails, it is necessary"<<endl <<" "<<sum<<" santimetre niton"<<endl; return 0; } Alf, честно говоря незнаю и нужно ли это?
|
|
« Последнее редактирование: 13-01-2009 18:02 от Вад »
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #25 : 03-12-2005 21:35 » |
|
... Alf, честно говоря незнаю и нужно ли это? Хм... Даже затрудняюсь ответить, такой поворот мне и в голову не приходил. С какой целью тогда была написана программа? Еще Козьма Прутков учил: "Бросая в воду камешки, смотри на круги, ими образуемые; иначе такое бросание будет пустою забавою." Чтобы написание подобной программы не стало пустой забавой, нужно одно из двух: либо получить выгодный подряд на связывание гвоздей нитками (в чем я сомневаюсь), либо пожелать научиться чему-то новому (что больше похоже на правду). Наиболее очевидный алгоритм, который первым приходит в голову, - это перебрать все комбинации и для каждой оценить суммарную длину нитей, после чего выбрать минимальную длину. Незатейливо, однако по моей прикидке потребует 2 N операций, а следовательно, будет работать лишь при N~10. Именно поэтому и спросил про сотню гвоздей - алгоритм, способный обсчитать сотню за разумное время, должен быть весьма элегантным, и мне хотелось бы на него посмотреть. В противном случае это тривиальный перебор, не представляющий никакого интереса.
|
|
|
Записан
|
|
|
|
kasper
Гость
|
|
« Ответ #26 : 03-12-2005 21:39 » |
|
да, наверно. я пока немогу делать привязку к таймеру. как это?
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #27 : 03-12-2005 21:52 » |
|
Засеки время в начале выполнения алгоритма и в конце. Благодарям простым алгебраическим операциям узнаешь как долго работате твой алгоритм. Это, если конечно именно это имелось ввиду.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
kasper
Гость
|
|
« Ответ #28 : 03-12-2005 21:54 » |
|
Это нужно отобразить в исходнике, если я правильно понял. Какими операторами или функциями?
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #29 : 03-12-2005 21:56 » |
|
Под винду пишешь? Среду разработки скажи.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
|