Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> бинарный поиск и рандомайзер для массива, решение задач 
:(
    Опции темы
Rauko
Дата 22.11.2014, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.6.2009

Репутация: нет
Всего: нет



ну, собственно вопросы: 
1) как реализовать бинарный поиск в массиве чисел, если есть массив и число, которое нужно найти?
2) как создать массив со случайными числами?

по первому - не представляю, как за задачу взяться;
по второму - задача была выявить в массиве число и напечатать его индекс, что собственно и было реализовано(задача на применение equals), но с фиксированным массивом выглядит как то не интересно и однообразно, а самосоздаваемый массив создать как то не получается( покажите нубу, как это делается
собственно сам код программы для второго пункта:
Код

// Создать массив случайных чисел. интерактивно запросить пользователя ввести число. 
// Сравнить число со всеми числами массива и определить индекс совпавшего числа в 
// массиве с введенным пользователем.

// Ex 1_7(7)
import java.util.*;

public class IndexMassiva {

    public static void main ( String[] args ) {
        int j = 10; // размер массива

        Integer[] nums = {19, 81, 76, 12, 3, 45, 18, 78, 7, 56}; // вариант для проверки,
                                    // жестко заданный массив, необходимый для проверки
                                    // работоспособности остального кода. Работает, но 
                                    // выглядит не интересно.
        System.out.print("Your random array is: ");
        for (int i = 0; i < j-1; i++)
            System.out.print(nums[i] + ", ");
        System.out.println(nums[j-1] + ".");
        System.out.print("Enter your number: ");
        Scanner sc = new Scanner(System.in);
        try {
            int userNum = sc.nextInt();
            for (int i = 0; i < j; i++ ){
                if ( nums[i].equals(userNum) ){
                //    i++;                    // с этой строкой мы получим не индекс,
                                            // а порядковый номер в массиве
                    System.out.println("Index of your number in this array is: " + i);
                    break;
                } else {
                    if ( i == j-1 ) {
                        System.err.println("There is no match in the array!");
                        break;
                    }    
                }
            }
            
        } catch ( Exception ex ) {
            System.err.println("Input ERROR!");
        } finally {
            sc.close();
        }
    }
}


по поводу названия написанного транслитом - я в курсе, что выглядит тупо и так не делается, файл создавался под эту задачку несколько месяцев назад(решаю в рандомном порядке и когда не решается сразу - откладывается в долгий ящик) и просто решила не менять...
PM MAIL   Вверх
Rauko
Дата 22.11.2014, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.6.2009

Репутация: нет
Всего: нет



второй вопрос отпал , для интересующихся, код принял сделующий вид:
Код

// Создать массив случайных чисел. интерактивно запросить пользователя ввести число. 
// Сравнить число со всеми числами массива и определить индекс совпавшего числа в 
// массиве с введенным пользователем.

// Ex 1_7(7)
import java.util.*;

public class IndexMassiva {

    public static void main ( String[] args ) {
        int sizeArr = 10; // размер массива
        int maxVal = 100; //максимальное значение случайного эллемента массива
        Integer[] nums = new Integer[sizeArr];
        for(int i = 0; i < sizeArr; i++){
            nums[i] = new Random().nextInt(maxVal);
        }
        System.out.print("Your random array is: ");
        for (int i = 0; i < sizeArr-1; i++)
            System.out.print(nums[i] + ", ");
        System.out.println(nums[sizeArr-1] + ".");
        System.out.print("Enter your number: ");
        Scanner sc = new Scanner(System.in);
        try {
            int userNum = sc.nextInt();
            for (int i = 0; i < sizeArr; i++ ){
                if ( nums[i].equals(userNum) ){
                //    i++;                    // с этой строкой мы получим не индекс,
                                            // а порядковый номер в массиве
                    System.out.println("Index of your number in this array is: " + i);
                    break;
                } else {
                    if ( i == sizeArr-1 ) {
                        System.err.println("There is no match in the array!");
                        break;
                    }    
                }
            }
            
        } catch ( Exception ex ) {
            System.err.println("Input ERROR!");
        } finally {
            sc.close();
        }
    }
}

PM MAIL   Вверх
baldina
Дата 23.11.2014, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(Rauko @  22.11.2014,  20:15 Найти цитируемый пост)
по первому - не представляю, как за задачу взяться;

сначала изучить тему. в вики даже код есть
PM MAIL   Вверх
Michael.de
Дата 25.11.2014, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 22.3.2005
Где: Deutschland

Репутация: нет
Всего: 9



Rauko, а если так: >> _https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(int[], int, int, int) <<
Но только если это для личных нужд, а не для курсовой/коллоквиума. Ибо нормальный преподаватель такое не пропустит smile

P.S.
1. если maxVal == "максимальное значение случайного эллемента массива", то добавляйте в 15 стр. единицу >>javadoc<< :
Код

nums[i]=new Random().nextInt(maxVal + 1 );

2. у Вас нет проверки на одинаковые элементы в массиве {7, 13, 22, 76, 22 ...}

P.S.S. форумный движок глючит с линками smile

Это сообщение отредактировал(а) Michael.de - 25.11.2014, 21:48
PM MAIL   Вверх
Rauko
Дата 25.11.2014, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.6.2009

Репутация: нет
Всего: нет



Michael.de,
мой бинарный поиск имеет такой вид - как дальше просто не могу понять... сижу в сети сейчас с телефона, прочитать что то проблематично...

Код

        double userNum = 0;
        read(userNum);
        int left = 0;
        int right = nums.length;
        
        for(int i = left; i < right; i++){
         if(userNum > nums[(right+left)/2]){
             left = (right+left)/2;
         } else right = (right+left)/2;
         //тут должно еще что то быть
        }


по поводу курсовой... я свои 9 курсачей и магистерскую уже сдала, но так как ничему полезному в универе не научили(кому нужен фартран и паскаль в наши дни?) учу сама яву - вокруг много объявлений, что нужны явисты... из последних "достижений" - 18 задач на массивы, дошла до последней, сижу и думаю, как ее можно реализовать... учитывая, что много лет не кодила с нуля - прогресс просто немыслемый прослеживается, особенно учитывая, что код получается рабочий и более менее универсальный в плане использования в подобных задачах

для "поржать":
Для проверки остаточных знаний учеников после летних каникул, учитель младших классов решил начинать каждый урок с того, чтобы задавать каждому ученику пример из таблицы умножения, но в классе 15 человек, а примеры среди них не должны повторяться. В помощь учителю напишите программу, которая будет выводить на экран 15 случайных примеров из таблицы умножения (от 2*2 до 9*9, потому что задания по умножению на 1 и на 10 — слишком просты). При этом среди 15 примеров не должно быть повторяющихся (примеры 2*3 и 3*2 и им подобные пары считать повторяющимися).

думаю надо начать уже учиться "резать" программы на мэйн и все остальное... а то моноблоки кода как то не айс выглядят, только для решения простых задач и годятся...

возвращаясь к задаче, о которой я спрашивала изначально: из всего условия
Код

//Kласс SortNumbers показывает, как можно отсортировать массив чисел типа double. 
//Hапишите программу, применяющую этот класс для сортировки 100 чисел с плавающей
//точкой. Затем в интерактивном режиме предложите пользователю ввести число и 
//отобразите соседние с ним в массиве большее и меньшее числа. что бы найти нужную
//позицию в отсортированном массиве, примените эффективный алгоритм двоичного 
//поиска.

по факту не реализовано на выходе только поиск и не до конца поняла с вводом-выводом - чего вообще автор задачи хочет получить на выходе? сравнение дроби? поиск дроби? поиск по целой части? учебник с задачами, откуда была взята задача, имеет пример вывода чисел с плавающей точкой, где выводятся следующие числа(это выдернуто из середины):
Код

48.2488618262337
49.24678010285631
49.506819030239846
51.43373831951806
51.5895493462739
51.801018076653435
51.82664476821673
53.034061555799575

совершенно неожиданно вылез вопрос - можно/нужно ли как то ограничивать дробную часть и если можно/нужно - как это сделать?

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

Это сообщение отредактировал(а) Rauko - 25.11.2014, 23:05
PM MAIL   Вверх
baldina
Дата 25.11.2014, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
я свои 9 курсачей и магистерскую уже сдала, но так как ничему полезному в универе не научили(кому нужен фартран и паскаль в наши дни?) учу сама яву

Rauko, по идее вас на примере паскаля и фортрана должны были научить программировать вообще, в т.ч. 
Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
научиться "резать" программы на мэйн и все остальное


похоже дело в том, что
Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
много лет не кодила с нуля

и отсутствии некоторых базовых знаний, увы. вам бы какую-нить книжку по алгоритмам и данным прочитать (того же Н.Вирта например, для начала), и по структурному программированию. можно сразу и по ООП, но наверно тяжело будет.

двоичный поиск и в африке двоичный, и на паскале мало отличается от варианта на java. 

Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
чего вообще автор задачи хочет получить на выходе?

ну как бэ ясно:
Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
отобразите соседние с ним в массиве большее и меньшее числа

по-моему, все предельно понятно

Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
можно/нужно ли как то ограничивать дробную часть и если можно/нужно - как это сделать?

что вы имеете в виду? если неточность вычислений с плавающей запятой и, в итоге, бессмысленность проверки на равенство, то здесь не ваш случай. у вас числа уже есть, ими не надо манипулировать, надо только найти искомое (или сказать что нет такого).

Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
сравнение дроби? поиск дроби? поиск по целой части?

что за ерунда. число хранится с предельной точностью, допустимой для типа. вводится с этой же точностью. просто сравнивайте, и все.

Добавлено @ 23:50
я догадываюсь, что вы хотите от значений типа 51.5895493462739 перейти к коротким, которые вам кажутся более осмысленными. но это лишь попытка переиначить задачу "под себя", введение дополнительных условий (к тому же усложняющих задачу). вы для начала справьтесь с исходной задачей, а уж потом фантазируйте  smile

например, если в вашем массиве окажутся те самые "страшные" значения, полученные через rand(), а пользователь введет "51", то программа ему скажет что число не найдено, и покажет два соседних - 49.506819030239846 и 51.43373831951806

кстати.
Цитата(Rauko @  25.11.2014,  22:55 Найти цитируемый пост)
if(userNum > nums[(right+left)/2]){
             left = (right+left)/2;
         } else right = (right+left)/2;

не так. все же поглядите в вики. и не стоит вычислять одно и то же 3 раза
один из вариантов мог бы выглядеть так
Код

mid=(right+left)/2;
if (userNum == nums[mid])
  // found!
else if (userNum < nums[mid])
  right = mid-1;
else // >
  left = mid+1;

если таки захотите сравнивать с какой-то точностью, замените == на Math.abs(userNum-nums[mid])<epsilon

Это сообщение отредактировал(а) baldina - 25.11.2014, 23:51
PM MAIL   Вверх
Rauko
Дата 26.11.2014, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 22.6.2009

Репутация: нет
Всего: нет



я сейчас нахожусь в какой то медвежьей дыре, у меня банально гугл грузится столько времени, что в ожидании можно суп сварить - скачать что либо вообще не реально, идут постоянные разрывы связи, даже на этом форуме с третьей-пятой попытки обновляется страница без ошибок.
на сутки выделено оператором 50 метров на прием - согласитесь, найти что то при условии постоянно перезагружаемой страницы - проблема, поэтому и спрашиваю тут, в надежде что дадут простой ответ хотя бы с указанием направления мысли для дальнейших действий, иначе бы искала какие то мануалы по выполнению нужных деййствий со всеми описаниями, еще бы и перебирала из вредности, что лучше описано автором той или иной книги


по поводу введенного пользователем числа... мы вводим число типа double, это понятно, но дальше интересно...
допустим, мы ввели 17.0, а ближайшее 16.3... , 17.4... и 17.7... - вопрос, как должна вести себя в этом случае программа? (написать то я это могу, я не знаю, что именно надо описывать в коде)
я просто не пойму, как именно требуется сравнивать числа - сравнивать ли только целую часть или и дробную тоже, если можно сравнивать число частично - как это правильно организовать.
то есть - обязательно ли по запросу программы копировать из списка число с хз каким количеством символов после запятой или можно ограничиться тремя знаками к примеру? если это допускается - как это выполнить корректно?

по поводу двоичного поиска - вроде понятно, попробую сегодня обкатать на работе в перерыв, будут вопросы - вернусь с ними


фантазировать в задаче это конечно хорошо, но пока позваляю себе эту вольность только в плане "красивого вывода на экран"(например - заставить двумерный массив выводиться красивыми ровными столбиками...). пока надо научиться выполнять то, что написано в задании

Это сообщение отредактировал(а) Rauko - 26.11.2014, 09:58
PM MAIL   Вверх
baldina
Дата 26.11.2014, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата(Rauko @  26.11.2014,  08:36 Найти цитируемый пост)
допустим, мы ввели 17.0, а ближайшее 16.3... , 17.4... и 17.7... - вопрос, как должна вести себя в этом случае программа? 

сообщать, что такого числа нет в массиве и выводить ближайшие меньшее и большее,
16.3 и 17.4

Добавлено через 59 секунд
Цитата(Rauko @  26.11.2014,  08:36 Найти цитируемый пост)
обязательно ли по запросу программы копировать из списка число с хз каким количеством символов после запятой

вообще ничего никуда копировать не надо, и вопрос отпадет сам собой.

Добавлено через 2 минуты и 52 секунды
Цитата(Rauko @  26.11.2014,  08:36 Найти цитируемый пост)
ограничиться тремя знаками к примеру? если это допускается - как это выполнить корректно?

сравнение:
Код

if (Math.abs(x-y)<1e-3) // x == y

вывод на экран
Код

System.out.format("%.3f",x);

PM MAIL   Вверх
Michael.de
Дата 26.11.2014, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 22.3.2005
Где: Deutschland

Репутация: нет
Всего: 9



Бинарный поиск (метод деления пополам / дихотомия) - поиск элемента в отсортированном массиве.
На картинке ниже показан поиск числа 76:
user posted image
Массив остаётся неизменным. И подмассивы не создаются. Лишь (после проверки) сдвигаются (сближаются друг с другом) правая и левая границы поиска.
Попробуйте проанализировать и/или сами себе объяснить принцип работы алгоритма с картинки (например, мне это помогает).
Отличие вышеприведённого примера от Вашего в том, что у Вас пользователь может ввести число, не являющееся элементом массива (находится: 1. между 2х элементов или 2. вообще за пределами массива)

P.S. Округлять, имхо, ничего не надо. Если юзер "угадал" число -> его и выдаёте в ответе. Попал между 2х элементов -> ответ: элем.слева, введённое с клав. число, элем.справа.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0563 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.