Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++] Циклический сдвиг элементов массива


Автор: Attention 28.11.2008, 18:15
Здравствуйте!

Помогите, пожалуйста, в решении задачи (на C++).

Суть задачи в следующем: 

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

1) Ввод исходных данных и вывод результата на экран производить в основной программе, решение  задачи осуществлять в созданной функции

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

Вот то, что получилось у меня (пока это только для строки символов):

Код

#include <iostream>
#include <conio.h>
char * sdvig(char * start, int a)
{
if (start == NULL ) return NULL;
 size_t len = strlen (start) + 1;
 if(len == 1) return NULL;

 char *r; //обрабатываемый символ в строке
 char * result = new char [len];
 char * result_pos = result;

 for(r=start; *r != '\0'; r++)
   {      
       while (*r!='\0')
        {
            *r+=a;
                                    *result_pos = *r;
             r ++;
             result_pos ++;
                        }
   }
   return result;
}

int main()
{
int k;
char * Array = new char [256];
std::cout<<"Vvedite massiv:"<<std::endl;
std::cin>>Array;

std::cout<<"Vvedite k:"<<std::endl;
std::cin>>k;

char * result = sdvig(Array, k);
std::cout<<result<<std::endl;
getch();
delete [] Array;
return 0;
}


Сдвиг вроде происходит, но он не циклический. Как исправить эту ошибку? Помогите, пожалуйста, желательно на примере.

Автор: safary 29.11.2008, 00:00
Осуществить циклический сдвиг элементов квадратной матрицы вправо на
k элементов таким образом: элементы 1-й строки сдвигаются в последний стол-
бец сверху вниз, из него − в последнюю строку справа налево, из нее − в первый
столбец снизу вверх, из него − в первую строку; для остальных элементов сдвиг
выполняется аналогичным образом. 
Код

#include <stdio.h>
#include <conio.h>
double GG ( double a[10][10], int p,int n,int m) 
{
          int i, j, k ;
          double temp,temp2,temp3;
 for(i=0; i < n/2; i++)
 {
  for(int z = p; z>0 ; z--) //кол-во сдвигов - к
  {
   for(j = i, temp = a[i][j]; j < n-1-i; j++)
   {
    temp2 = a[i][j+1];
    a[i][j+1] = temp;
    temp=temp2;
   }
   for(k = i+1; k < m-i; k++)
    {
    temp3=temp;
    temp=a[k][j];
    a[k][j]=temp3;
    }
   for( j--, k--; j >= i; j--)
    {
    temp3=temp;
    temp=a[k][j];
    a[k][j]=temp3;
    }
   for(j++, k--; k >= i; k--)
    {
    temp3=temp;
    temp=a[k][j];
    a[k][j]=temp3; 
  }}}
  return a[10][10];

}

int main()
{
 int p, n, m, i, j;
 double a[10][10];
       {
        printf("Vvedite n,m \n");
        scanf ("%d %d",&n,&m);
        /*n=4;
        m=4;*/
        }

        printf("Vvedite elementy matricy\n");
        for(i=0;i<n;i++)
        for(j=0;j<m;j++)
        {
          printf("a[%d][%d]=",i,j);
          scanf("%lf",&a[i][j]);
         }
         for(i=0;i<n;i++)
          {
           for(j=0;j<m;j++)
            {
             printf("%2.lf", a[i][j]);
            }
             printf ("\n");
            }
          {printf("Vvedite k\n");
          scanf ("%d",&p);
          GG(a,p,n,m); 
          for(i=0;i<n;i++)
          {
           for(j=0;j<m;j++)
            {
             printf("%2.lf", a[i][j]);
            }
             printf ("\n");
            }
getch();
  }
return 0;
}

Автор: Dov 29.11.2008, 07:15
Код
#define SIZE 256

template <class T>
T * sdvig( T *start, int size, int a )
{
    T  *result    = new T[size + 1];
    memcpy( result, start, sizeof( T ) * size );

    while( a-- )
    {
        T        tmp    = *result;
        T       *r    = result;
        int        i;

        for( i = 0; i < ( size - 1 ); i++ )
            *( r + i ) = *( r + i + 1 );

        *( r + i ) = tmp;
    }

    return result;
}

int main()
{
    setlocale( LC_ALL, ".1251" );

    int        k;
    char    ArrayChr[SIZE];
    int        ArrayInt[SIZE];
    int        sz;

    std::cout << "Введите строку символов:\n";
    std::cin.getline( ArrayChr, SIZE );
    sz = strlen( ArrayChr );

    std::cout << "Введите k: ";
    std::cin >> k;

    char   *resultChr    = sdvig( ArrayChr, sz, k );
    *( resultChr + sz ) = '\0';
    std::cout << resultChr << std::endl;

    std::cout << "Введите размер массива целых чисел: ";
    std::cin >> sz;    

    std::cout << "Введите массив целых чисел:\n";
    for( int i = 0; i < sz; i++ )
        std::cin >> *( ArrayInt + i );

    std::cout << "Введите k: ";
    std::cin >> k;

    int       *resultInt    = sdvig( ArrayInt, sz, k );
    for( int i = 0; i < sz; i++ )
        std::cout << *( resultInt + i ) << ' ';

    std::cout << std::endl;

    delete[] resultChr;
    delete[] resultInt;

    return 0;
}

Автор: Attention 29.11.2008, 11:29
Dov, спасибо большое, Вы мне очень помогли.   smile  

Не могли бы вы пояснить что означает:

1: #define SIZE 256

26: setlocale( LC_ALL, ".1251" );

И обязательно ли делать это через классы? К сожалению, я в них не сильна, изучение C++ началось не так давно.. Желательно бы пока обойтись без них.

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

Функция sdvig должна быть перегруженной. 

Автор: Dov 29.11.2008, 13:10
Attention, ты бы литературу почитала бы для начала....  smile 
Может так понятней будет..  держи.. 
Код
char * sdvig( char *start, int a )
{
    // находим длину строки
    int    size    = strlen( start );    
    
    // выделяем память под результирующую строку
    char   *result    = new char[size + 1];

    // копируем в неё исходную строку
    strcpy( result, start );
    
    // цикл по количеству позиций, подлежащих смещению
    while( a-- )
    {
        char    tmp    = *result;             // запоминаем значение первого элемента
        char   *r;                         // указатель на начало результирующей строки
        
        // цикл смещения элементов массива на одну позицию влево, 
        // текущему элементу присваивается значение следующего за ним элемента
        for( r = result; *( r + 1 ); r++ )
            *r = *( r + 1 );
        
        // последнему элементу присваивается значение переменной tmp,
        // таким образом, последний элемент получил значение первого
        *r = tmp;
    }

    return result;
}

int * sdvig( int *start, int size, int a )
{
    int       *result    = new int[size];
    int        i;

    for( i = 0; i < size; i++ )
        *( result + i ) = *( start + i );

    while( a-- )
    {
        int        tmp    = *result;
        int       *r    = result;        

        for( i = 0; i < size - 1; i++ )
            *( r + i ) = *( r + i + 1 );

        *( r + i ) = tmp;
    }

    return result;
}

int main()
{
    // для отображения русских символов
    setlocale( LC_ALL, ".1251" );

    const   int SIZE  = 256;    
    char        ArrayChr[SIZE];
    int         ArrayInt[SIZE];
    int         k, sz;

    std::cout << "Введите строку символов:\n";
    std::cin.getline( ArrayChr, SIZE );

    // если строка не пустая
    if( *ArrayChr )
    {
        std::cout << "Введите k: ";
        std::cin >> k;

        char   *resultChr    = sdvig( ArrayChr, k );

        std::cout << resultChr << std::endl;

        delete[] resultChr;
    }

    std::cout << "Введите размер массива целых чисел: ";
    std::cin >> sz;    
    
    // если в массиве больше одного элемента, иначе нечего будет смещать
    if( sz > 1 )
    {
        std::cout << "Введите массив целых чисел:\n";
        for( int i = 0; i < sz; i++ )
            std::cin >> *( ArrayInt + i );

        std::cout << "Введите k: ";
        std::cin >> k;

        int       *resultInt    = sdvig( ArrayInt, sz, k );
        for( int i = 0; i < sz; i++ )
            std::cout << *( resultInt + i ) << ' ';

        delete[] resultInt;
    }

    std::cout << std::endl;

    return 0;
}

Автор: Attention 29.11.2008, 14:15
Dov, так намного понятнее smile 

Литературу читать пробовала, но за краткие сроки большого материала все равно не охватишь, поэтому легче, когда объяснение происходит "на пальцах"  smile 

Огромное спасибо.


Автор: lllbenderlll 16.3.2010, 15:42
короче похер на типы исходного массива ... важна длинна и сдвиг:

Код


template <class m> void sdvig_cicl(m*& mas,int len,int sdvig);
template <class m> void sdvig_cicl(m*& mas,int len,int sdvig){
//массив    mas-указатель на 0-й элемент массива тобиш на сам массив
//длинна массива len
//на сколько нужно сдвинуть sdvig (если sdvig>0 то --> если нет то <-- на заданное число строк)

m* mas_temp = new m [len];

if (sdvig>len){sdvig%=len;}

if (sdvig<0){
    sdvig=(-sdvig)%len;
    sdvig=len-sdvig;
    }

    int z=0;
    for (int i = sdvig; i < len; i++){
        mas_temp[i]=mas[z];
        z++;
        }

    z=len-sdvig;
    for (int i = 0; i < sdvig; i++){
        mas_temp[i]=mas[z];
        z++;
        }

    for (int i =0; i < len; i++){
        mas[i]=mas_temp[i];
        }
    }



 smile  smile  smile  smile  smile  smile 
 smile  smile  smile 


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)