Форум программистов, компьютерный форум CyberForum.ru

Определить когда массив меняет знак. - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
16.08.2011, 19:17     Определить когда массив меняет знак. #1
Дан массив чисел, как положительных так и отрицательных.

Нужно определить номер элемента, который первым меняет знак с отрицательного на положительный и номер элемента, который последним меняет знак с положительного на отрицательный .

Например:

-1, 1, -4, 2, 5, -6, -7
Тут знак первым меняет второй элемент, а последним шестой.

При этом если массив не меняет знак вообще, в ответы записывались бы "0".

Пожалуйста, напишите циклы, которые позволят это сделать, очень нужно.

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

Заранее благодарю всех откликнувшихся.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.08.2011, 19:17     Определить когда массив меняет знак.
Посмотрите здесь:

Определить сколько раз массив меняет знак на противоположный C++
Определить сколько раз массив меняет знак C++
(CИ)26. Определить сколько раз последовательность из N произвольных чисел меняет знак C++
C++ Массив: Определить, сколько раз меняется знак в данной последовательности чисел, запомнить номера позиций, в которой происходит смена знака.
C++ Написать программу, которая меняет знак всех нечетных элементов двумерного массива
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
16.08.2011, 19:29     Определить когда массив меняет знак. #2
Ну просто нереально сложная задача
C
1
2
3
4
5
6
7
8
9
10
11
12
int i, flag = 0;
for(i = 1; i < n; ++i)
{
    if(array[i - 1] * array[i] < 0)
    {
        if(!flag)
            printf("first = %d\n", i);
        flag = i;
    }
}
if(flag)
    printf("last = %d\n", flag);
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
16.08.2011, 19:40     Определить когда массив меняет знак. #3
Еще раз перечитал задание, нужно так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
 
#define n 7
 
int main()
{
    int array[n]={-1,1,-4,2,5,-6,-7};
    int i, flag = 0;
    for(i = 1; i < n; ++i)
    {
    if(array[i - 1] * array[i] < 0)
    {
        if(!flag && array[i] > 0)
        printf("first = %d\n", i), flag = i;
        else if(flag && array[i] < 0)
        flag = i;
    }
    }
    if(flag)
    printf("last = %d\n", flag);
 
    return 0;
}
Нумерация печатаемых индексов начинается с нуля! Т.е. приведенным в твоем примере номерам 2 и 6 соответствуют мои 1 и 5.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
16.08.2011, 20:05     Определить когда массив меняет знак. #4
Может тут лучше два раза пройтись по массиву, с начала и с конца?
Осторожно, плохой код!
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <assert.h>
 
#define SIZE 7
 
size_t first_of_sign_changing(const int *p, size_t size) 
{
    size_t i = 1, sign = 0;
    assert(p);
 
    sign = (*p) >> 31;
    while (size-- && sign == *(p + i) >> 31) {
        ++i;
    }
 
    return i;
}
 
size_t last_of_sign_changing(const int *p, size_t size)
{
    size_t i = size - 1, sign = 0;
    assert(p);
 
    sign = *(p + i) >> 31;
    while (size-- && sign == *(p + i) >> 31) {
        --i;
    }
 
    return i;
}
 
int main() 
{
    int data[SIZE] = { 
        -1, -1, 2, -1, 1, -6, -7 
    };
 
    printf("%lu, %lu\n", 
        first_of_sign_changing(data, SIZE),
        last_of_sign_changing(data, SIZE));
 
    return 0;
}
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
16.08.2011, 20:08     Определить когда массив меняет знак. #5
А вообще, ИМХО, тут ничего от исходного массива отнимать не нужно, а нужно рассматривать исходный массив, сравнивая его элементы с пороговым значением. Условия сильно от этого измениться не должны.
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
16.08.2011, 22:11  [ТС]     Определить когда массив меняет знак. #6
Ребят, прошу прощения, я совсем начинающий и половину не понял((

У меня есть массив Ar[n] (n известно заранее) и мне нужно получить 2 значения , скажем n1 и n2, чтобы использовать их в дальнейшем в той-же программе с другой целью. И есть порог, скажем 10. Нужно определить 1) когда массив 1 раз превысит порог (n1) 2)когда массив последний раз станет ниже порога (n2). Если массив ни разу не становится выше 10, n1 и n2 сделать нулями

Первая задача:

C++
1
2
3
4
5
6
 int i, n1=0 ;
    for(i = 1; i < n; ++i)
    {
    if (Ar[i-1]<10 && Ar[i]>10 )
    n1=i; 
    }
Но как сделать, чтобы цикл остановился, когда условие выполнится 1 раз? Ко второй задаче не знаю как и приступить. Как пройтись по массиву с конца? Если будет не сложно, напишите оба цикла, буду крайне благодарен.

Еще раз прошу прощения, совсем не имел дела с программированием, пришлось столкнутся, вот пытаюсь разобраться.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
17.08.2011, 05:04     Определить когда массив меняет знак. #7
Отнимать тут пороговое значение от элементов массива - это лишняя работа.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <stdlib.h>
 
#define THRESHOLD 10
#define N 7
 
int first_element_exceeding_threshold(int* array, size_t n, int threshold);
int last_element_preceeding_threshold(int* array, size_t n, int threshold);
 
int main()
{
    int n1, n2;
    int array[N] = {10, 15, 9, 18, 14, 3, 10};
 
    n1 = first_element_exceeding_threshold(array, N, THRESHOLD);
    n2 = last_element_preceeding_threshold(array, N, THRESHOLD);
 
    printf("The index of the first element, which value exceeds the theshold %d: %d\n", THRESHOLD, n1);
    printf("The index of the last element, wnich value preceeds the theshold %d: %d\n", THRESHOLD, n2);
    
    exit(0);
}
 
int first_element_exceeding_threshold(int* array, size_t n, int threshold)
{
    size_t i;
    
    for(i = 0; i < n; ++i)
    if(array[i] > threshold)
        return i + 1;
 
    return 0;
}
 
int last_element_preceeding_threshold(int* array, size_t n, int threshold)
{
    size_t i;
 
    for(i = n; i > 0; --i)
    if(array[i - 1] < threshold)
        return i;
 
    return 0;
}
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
17.08.2011, 08:53     Определить когда массив меняет знак. #8
Цитата Сообщение от pistol Посмотреть сообщение

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

Заранее благодарю всех откликнувшихся.
Не. Если порог меньше минимального элемента, то после вычитания порога в массиве отрицательных все равно не будет. И ноль как считать - смена знака или нет?
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
17.08.2011, 14:42  [ТС]     Определить когда массив меняет знак. #9
Nameless One спасибо, но у меня все эти операции должны быть внутри других циклов и почему-то они не работают. Приведу свой код. Никак не пойму что не так. Заранее спасибо

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
for( y = 0; y < nHeight; y++ )  
   {
    for( x = 0; x < nWidth; x++ )   /циклы внутри которых нужно работать с массивом
    {       
           
    size_t i1;
        int t1=0;
    for(i1 = 0; i1 < Ar.size(); ++i1)   /Ar.size() - размер массива
       if(Ar[i1] > 2300)
           {
           t1=i1;
           return i1 + 1;
           }
        
    size_t i2;
    int t2=0;
        for(i2 = t1+30; i2 <Ar.size(); ++i2)
       if(Ar[i2] < 2300)
            {   
         t2=i2;
             return i2 + 1;
         }
 
        if (t1=0)
        t2=0;
       
       Res1=Ar2[t1];   /res1 и res2 заданны ранее, Ar2 -второй массив   
       Res2=Ar2[t2];
        
    
        
    }
   }
Добавлено через 43 минуты
Чуть не забыл, в последнем примере условия немного поменялись, но это уже не столь важно.
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
17.08.2011, 16:27     Определить когда массив меняет знак. #10
pistol, приведи полностью постановку задачи, а то я из твоего, хмм, кода ничего не понял
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
17.08.2011, 16:58  [ТС]     Определить когда массив меняет знак. #11
Ну есть довольно длинная программа, в которой есть массивы Ar и Ar1, известны их размеры ArSize. Нужно определить номер элемента t1 когда массив Ar впервые превосходит 2300 и вычислить значение Ar2[t1]. Я делаю так, но цикл не выплняется (программа выдает ошибку).

C++
1
2
3
4
5
6
7
8
9
10
11
size_t i1;
int t1=0;
for(i1 = 0; i1 < ArSize; ++i1)
if(Ar[i1] > 2300)
{
t1=i1;
return i1 + 1;
}
 
double Res;
Res=Ar2[t1];
При этом если сделать например так, то всё работает корректно, то есть дело в цикле.

C++
1
2
3
4
int t1=10;
 
double Res;
Res=Ar2[t1];
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
17.08.2011, 17:44     Определить когда массив меняет знак. #12
Ну, насколько я понял, первый цикл у тебя ищет первое привышение порогового значения, а второй - последнее принижение (поправь, если я не прав). Так вот, если у тебя найдено первое привышение, то у тебя происходит возврат из функции и второе значение (т.е. последнее принижение) уже не ищется. Аналогично, даже если у тебя начался поиск последнего принижения, то если оно у тебя найдено (а по твоему коду я бы не сказал, что во втором цикле ищется именно оно), то опять происходит возврат из функции и значения Res1 и Res2 не устанавливаются.
Цитата Сообщение от pistol Посмотреть сообщение
спасибо, но у меня все эти операции должны быть внутри других циклов и почему-то они не работают
никто не мешает тебе взять мой код и поместить его внутри твоих циклов
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
17.08.2011, 17:58  [ТС]     Определить когда массив меняет знак. #13
А как сделать, чтобы он останавливал цикл когда условие выполняется, значения t1 и t2 устанавливались, но программа не возвращалась из функции?

Никто не мешает тебе взять мой код и поместить его внутри твоих циклов

Там у тебя массив задается в коде, не мог бы ты его написать для случая когда массив задан заранее, просто не могу разобраться?

П.С. Да, задача немного изменилась, но как я уже написал второй цикл можно сделать по аналогии с первым, главное разобраться.

Заранее спасибо
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
17.08.2011, 18:05     Определить когда массив меняет знак. #14
Цитата Сообщение от pistol Посмотреть сообщение
А как сделать, чтобы он останавливал цикл когда условие выполняется, значения t1 и t2 устанавливались, но программа не возвращалась из функции?
break (лучше) либо дополнительное условие в for (хуже)

Цитата Сообщение от pistol Посмотреть сообщение
Там у тебя массив задается в коде
ну так сделай заполнение массива так же, как он заполняется у тебя (читай: возьми мой исходник и переделай его под себя). Как заполняется массив - это несущественно. А имеет значение лишь поиск необходимых элементов, который у меня выполняют функции first_element_exceeding_threshold и last_element_preceeding_threshold.
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
17.08.2011, 18:50  [ТС]     Определить когда массив меняет знак. #15
Спасибо большое, break помогло, всё оказалось банально просто. сори за глупость, совсем не имел опыта. Nameless One смотри личку.
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
14.09.2011, 19:27  [ТС]     Определить когда массив меняет знак. #16
Ребят, помогите пожалуйста, задача немного усложнилась. Теперь в массиве надо найти самый большой участок, лежащий ниже порога (границы данного участка). Чтобы было немного понятнее, приложил рисунок. Чёт не знаю даже как приступить к задаче даже в теории((

Заранее спасибо
Миниатюры
Определить когда массив меняет знак.  
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
14.09.2011, 20:08     Определить когда массив меняет знак. #17
pistol, уточни пожалуйста. Самых длинный по размеру отрезок или самый "глубокий" отрезок (то есть отрезок, где лежит минимум массива)?
Если первое, то надо найти первый отрезок. А потом по принципу поиска максимума искать отрезки более длинные.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.09.2011, 21:59     Определить когда массив меняет знак.
Еще ссылки по теме:

Линейный массив содержит значения некоторой функции.Определить сколько раз функция сменила знак. C++
Дан массив ненулевых целых чисел. Определить, сколько раз элементы массива при просмотре от его начала меняют знак. Например, в массиве 10, -4, 12, -4 C++
C++ Определить, сколько раз меняется знак в последовательности чисел, введенных с клавиатуры, применив массив

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
pistol
1 / 1 / 0
Регистрация: 16.08.2011
Сообщений: 18
14.09.2011, 21:59  [ТС]     Определить когда массив меняет знак. #18
Самый длинный по размеру.
Yandex
Объявления
14.09.2011, 21:59     Определить когда массив меняет знак.
Ответ Создать тему
Опции темы

Текущее время: 01:23. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru