0 / 0 / 0 Регистрация: 22.09.2012 Сообщений: 19 |
|
1 |
|
Алгоритмы (найти последнюю перемену знака в массиве)10.05.2013, 21:34. Показов 543. Ответов 7
Подскажите,как найти последнюю перемену знака в массиве,без использования циклов и рекурсии.
0 |
244 / 245 / 38 Регистрация: 08.04.2013 Сообщений: 927 |
|
10.05.2013, 21:38 |
2 |
Fissil, что значит “перемена знака в массиве”?
0 |
0 / 0 / 0 Регистрация: 22.09.2012 Сообщений: 19 |
|
10.05.2013, 21:42 [ТС] |
3 |
ну перемена знака,когда после положительного элемента идет отрицательный,либо наоборот
0 |
Genn55 413 / 250 / 118 Регистрация: 26.12.2012 Сообщений: 786 |
||||
10.05.2013, 22:49 |
4 |
|||
Наверное как то так
0 |
244 / 245 / 38 Регистрация: 08.04.2013 Сообщений: 927 |
|
10.05.2013, 23:19 |
5 |
Genn55, и как это решает задачу?
0 |
413 / 250 / 118 Регистрация: 26.12.2012 Сообщений: 786 |
|
10.05.2013, 23:26 |
6 |
Извиняюсь.Проверил.Плохо.
0 |
2020 / 1619 / 489 Регистрация: 31.05.2009 Сообщений: 3,005 |
|
10.05.2013, 23:38 |
7 |
Подскажите,как найти последнюю перемену знака в массиве,без использования циклов и рекурсии. Каков бы ни был алгоритм элементы в любом случае нужно как-то перебирать Или вы имеете в виду алгоритм из STL? В таком случае, учитывая что нужно найти последнюю пару соседних элементов с разными знаками: std::adjacent_find + свой предикат + reverse_iterator.
0 |
Genn55 413 / 250 / 118 Регистрация: 26.12.2012 Сообщений: 786 |
||||||||
11.05.2013, 02:51 |
8 |
|||||||
Как то так.С 0 добавить условие,если нужно.
Добавлено через 2 часа 5 минут
0 |
Самый простой, да и надежный путь – наивное решение со счетчиком и циклом. Но это не наш метод. Для начала текст, потом код.
Возьмем вот такой массив как пример: [-3, -4, 5, -5, 0, 3, -3]
и оставим вместо самих чисел только их знак: 1
для положительных, -1
для отрицательных: [-1, -1, 1, -1, 1, 1, -1]
. Теперь будем брать последовательно два рядом стоящих числа (их знака). Вот так будет выглядеть последовательность:
-3, -4 (-1, -1);
-4, 5 (-1, 1);
5, -5 (1, -1);
-5, 0 (-1, 1);
0, 3 (1, 1);
3, -3 (1, -1).
Таких пар чисел будет ровно len(list) - 1
, т.е. длина списка минус 1. Представьте, что все числа положительны. Тогда сумма всех пар знаков (т.е. единиц) будет равна (len(list) - 1) * 2
. Хорошо, если вы не просто поверите на слово, а проверите данный тезис. Каждая пара чисел с разными знаками уменьшает сумму на 2. Обозначим сумму этих пар знаков как summ
и исходя из всего вышесказанного количество смен знаков будет равно ((len(list) - 1) * 2 - summ) / 2
. Распишем сумму как сумму элементов массива с индексами:
summ := |a0 + a1| + |a1 + a2| + |a2 + a3| + |a3 + a4| + |a4 + a5| + |a5 + a6|, где |...|
– это модуль числа. На этом в общем-то и все:
import random
# Все, что касается знаков спихиваем на библиотеку
# Ибо можно попасть на всякие нехорошие вещи типа -0.0, nan, -nan и т.д.
# Однако copysign вычисляет в процессе арктангенс(!!!) от числа и нельзя сказать, что
# это очень быстро. Для ультра быстроты можно поиграть с битовыми сдвигами
from math import copysign
LIST_LEN = 7
target_list = [random.randint(-15, 15) for _ in range(LIST_LEN)]
only_ones_list = [copysign(1, element) for element in target_list]
summ = 0
for i in range(len(only_ones_list) - 1):
summ += abs(only_ones_list[i] + only_ones_list[i + 1])
sign_change_count = ((len(only_ones_list) - 1) * 2 - summ) / 2
print(target_list)
print(only_ones_list)
print(sign_change_count)
>>> [-6, 12, -3, -11, -12, -13, 7]
>>> [-1, 1, -1, -1, -1, -1, 1]
>>> 3.0
Список из знаков можно не составлять, конечно же, а сразу пройти по исходному.
Теперь самое сложное – чем данное может быть полезным. Во-первых, никаких рассуждений о знаковости нуля или nan или еще чего угодно. Мы используем стандартную функцию и не паримся. Теоретически можно обойтись совсем без условных операторов (внутри abs и copysign) – получение знака и модуль числа можно попробовать вычислить хитрыми битовыми операциями. Также теоретически сложение быстрее, чем умножение, однако разница будет заметна на больших массивах.
#pragma hdrstop #pragma argsused #include <iostream.h> #include <conio.h> int main(int argc, char* argv[]) { int mas [10]; char ch; int mesto[10]; int count=0; for (int i=0; i<10; i++) { cin>>mas[i]; } if (mas[0]>=0) ch = '+'; else ch = '-'; for(int i=0; i<10; i++) { if (mas[i]>=0) { if (ch=='-') { ch='+'; mesto[count]=i; count++; } } else { if (ch=='+') { ch='-'; mesto[count]=i; count++; } } } cout<<"a sign changes after the "; for (int i=0; i<count; i++) { if (i!=0) cout<<","<<mesto[i]; else cout<<mesto[i]; } cout<<" array cell(s)"<<"n"; cout<<"a sign changes "<<count<<" times"; getch(); }
Форум программистов Vingrad
Модераторы: Poseidon |
Поиск: |
|
[Java] Cмена знака в последовательности чисел |
Опции темы |
Merhaba |
|
||
Шустрый Профиль Репутация: нет
|
Добрый Вечер!!!
|
||
|
|||
frikey |
|
||
Senior Sys Engineer Профиль
Репутация: нет
|
Пожалуйста:
|
||
|
|||
Merhaba |
|
||
Шустрый Профиль Репутация: нет
|
frikey, |
||
|
|||
Merhaba |
|
||
Шустрый Профиль Репутация: нет
|
frikey,
(например, в последовательности –5, –2, 9, 1, 0, 4, –3 знак меняется дважды: с минуса на плюс, затем с плюса на минус). |
||
|
|||
frikey |
|
||
Senior Sys Engineer Профиль
Репутация: нет
|
Прошу прощения. Глупейшая ошибка Вот корректный код:
|
||
|
|||
Merhaba |
|
||
Шустрый Профиль Репутация: нет
|
frikey,
|
||
|
|||
frikey |
|
||
Senior Sys Engineer Профиль
Репутация: нет
|
Суть в следующем: |
||
|
|||
Merhaba |
|
||
Шустрый Профиль Репутация: нет
|
frikey, |
||
|
|||
|
Правила форума “Центр помощи” | |
|
ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Более подробно с правилами данного раздела Вы можете ознакомится в этой теме. Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) |
0 Пользователей: |
« Предыдущая тема | Центр помощи | Следующая тема » |
Мне нужно написать функцию, которая берет элементы массива и меняет знак (например, 3 –> -3 или -3 –> 3). Дело в том, что мне нужно изменить все значения, кроме первых трех целых чисел в массиве, а затем отобразить весь массив с неизмененными и измененными значениями.
Вот мой код
#include<stdio.h>
#include<stdlib.h>
void change_sign(int x[], int n)
{
int *ptr[n];
int i;
for(i = 0; i < n; i++)
{
ptr[i] = &x[i+3];
}
for(i = 0; i < n; i++)
{
x[i] = *ptr[i] * (-1);
printf("%dn", x[i]);
}
}
int main()
{
int arr [10] = {-5, 13, -2, 5, 8, -54, 82, -4, 9, -43};
change_sign(arr, 10);
return 0;
}
Это, очевидно, не работает, оно показывает только измененные числа и некоторые случайные числа в конце.
Любая помощь будет принята с благодарностью.
Перейти к ответу
Данный вопрос помечен как решенный
Ответы
2
Попробуй это
#include<stdio.h>
#include<stdlib.h>
void change_sign(int x[], int n)
{
int i;
for(i = 0; i < n; i++)
{
if (i>2)
x[i] = -x[i];
printf("%dn", x[i]);
}
}
int main()
{
int arr [10] = {-5, 13, -2, 5, 8, -54, 82, -4, 9, -43};
change_sign(arr, 10);
return 0;
}
Ваша ошибка связана с выходом за пределы
Если вы не хотите использовать указатель, попробуйте что-то вроде
void change_sign(int x[], int n)
{
for(int i = 3; i < n; i++)
{
x[i] = -x[i] ;
}
}