Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Описать процедуру Invert(A, N), меняющую порядок следования элементов вещественного массива A размера N на противоположный

Описать процедуру Invert(A, N), меняющую порядок следования элементов вещественного массива A размера N на противоположный (инвертирование массива). Массив A является входным и выходным параметром. С помощью этой процедуры инвертировать массивы A, B, C размера NA, NB, NC соответственно.
Ответ: Подскажите с заданием:
Описать функцию типа void Hill(A, N), меняющую порядок элементов вещественного массива A размера N на следующий: наименьший элемент массива располагается на первом месте, наименьший из оставшихся элементов — на последнем, следующий по величине располагается на втором месте, следующий — на предпоследнем и т. д. (в результате график значений элементов будет напоминать холм). Массив A является входным и выходным параметром. С помощью этой функции преобразовать массивы A, B, C размера NA, NB, NC соответственно.
Вопрос: Процедура, на входе которой подаются массивы разных размеров

Здравствуйте.

Подскажите пожалуйста как организовать процедуру на входе в которую подаются массивы разных размеров, а она вычисляет кол-во элементов в этом массиве, или индекс последнего элемента.
Ответ: Hitoku Просто мне нужно применить одну процедуру к массивам разных размеров.
И Puporev вроде подсказал дельный способ.
Вопрос: Явная специализация шаблона.

Явная специализация шаблона класса в одной единице трансляции а его объявление в другой. Прекрасно работает в msvc но под gcc 4.8 явная специализация не выполняется.(class xxx<test>)
Это стандарт или есть способы решить вопрос?
Условный пример.
Файл 1
    template<typename T>
    class xxx
    {
     T * operator() { throw "bla bla"; }
    }

Файл 2
    class test
    {
      virtual void bla() = 0;
    };

Файл 3
    class testimpl : public test
    {
      virtual void bla(){}
    };
     
    template<>
    class xxx<test>
    {
     test * operator()()
     {
       return new testimpl();
     }
    }


Где то в коде
    test * ltest = xxx<test>()();
Сообщение отредактировано: Urich -
Ответ:
Цитата Urich @
Знаете способ как это разрулить, нужна черная магия в виде опции компилятора.

Простейший способ - вынести шаблон и специализацию в заголовочный файл, который уже и подключать куда надо (ODR на шаблоны не распространяется).
Вопрос: Явная специализация шаблона класса и ее методы

На 93 строке явная специализация шаблона класса под char.
Но я нигде не могу найти, как мне правильно записать методы для него. Если тело методов сделать в классе, то все нормально(как инлайн, получается), а вот снаружи никак не пойму.
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include <iostream>
 
using std::cout;
using std::cin;
 
char ch = '/';
///////////////////////////////////////////////////////////
template <class T>
class fraction
{
private:
    T numerator;
    T denominator;
public:
    fraction()
    {
        numerator = 0; denominator = 0;
    }
    fraction(T num, T den)
    {
        numerator = num; denominator = den;
    }
    void get()
    {
        cout << "Введите дробь: ";
        cin >> numerator >> ch >> denominator;
    }
    void display()
    {
        cout << "Результат равен: " << numerator << ch << denominator << std::endl;
    }
    void lowterms();
    fraction operator+(fraction d);
    fraction operator-(fraction d);
    fraction operator*(fraction d);
    fraction operator/(fraction d);
};
///////////////////////////////////////////////////////////
template <class T>
fraction<T> fraction<T>::operator+(fraction d) {
    T tn, td;
    tn = numerator * d.denominator + denominator * d.numerator;
    td = denominator * d.denominator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <class T>
fraction<T> fraction<T>::operator-(fraction d) {
    T tn, td;
    tn = numerator * d.denominator - denominator * d.numerator;
    td = denominator * d.denominator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <class T>
fraction<T> fraction<T>::operator*(fraction d) {
    T tn, td;
    tn = numerator * d.numerator;
    td = denominator * d.denominator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <class T>
fraction<T> fraction<T>::operator/(fraction d) {
    T tn, td;
    tn = numerator * d.denominator;
    td = denominator * d.numerator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <class T>
void fraction<T>::lowterms()             // сокращение дроби
{
    T tnum, tden, temp, gcd;
    tnum = labs(numerator);                 // используем неотрицательные
    tden = labs(denominator);                 // значения (нужен cmath)
    if( tden == 0 )                   // проверка знаменателя на 0
    { cout << "Недопустимый знаменатель!"; exit(1); }
    else if( tnum == 0 )              // проверка числителя на 0
    { numerator=0; denominator = 1; return; }
// нахождение наибольшего общего делителя
    while(tnum !=0)
    {
        if( tnum < tden )            // если числитель больше знаменателя,
        { temp=tnum; tnum=tden; tden=temp; } //меняем их местами
        tnum = tnum - tden;          // вычитание
    }
    gcd = tden;                      // делим числитель и знаменатель на
    numerator = numerator / gcd;                 // полученный наибольший общий делитель
    denominator = denominator / gcd;
}
///////////////////////////////////////////////////////////
template <>
class fraction<char>
{
private:
    char numerator;
    char denominator;
public:
    fraction()
    {
        numerator = 0; denominator = 0;
    }
    fraction(char num, char den)
    {
        numerator = num; denominator = den;
    }
    void get()
    {
        cout << "Введите дробь: ";
        cin >> numerator >> ch >> denominator;
    }
    void display()
    {
        cout << "Результат равен: " << numerator << ch << denominator << std::endl;
    }
    void lowterms();
    fraction operator+(fraction d);
    fraction operator-(fraction d);
    fraction operator*(fraction d);
    fraction operator/(fraction d);
};
///////////////////////////////////////////////////////////
template <>
fraction<char> fraction<char>::operator+(fraction d) {
    char tn, td;
    tn = numerator * d.denominator + denominator * d.numerator;
    td = denominator * d.denominator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <>
fraction<char> fraction<char>::operator-(fraction d) {
    char tn, td;
    tn = numerator * d.denominator - denominator * d.numerator;
    td = denominator * d.denominator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <>
fraction<char> fraction<char>::operator*(fraction d) {
    char tn, td;
    tn = numerator * d.numerator;
    td = denominator * d.denominator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <>
fraction<char> fraction<char>::operator/(fraction d) {
    char tn, td;
    tn = numerator * d.denominator;
    td = denominator * d.numerator;
    return fraction(tn, td);
}
///////////////////////////////////////////////////////////
template <>
void fraction<char>::lowterms()             // сокращение дроби
{
    char tnum, tden, temp, gcd;
    tnum = labs(numerator);                 // используем неотрицательные
    tden = labs(denominator);                 // значения (нужен cmath)
    if( tden == 0 )                   // проверка знаменателя на 0
    { cout << "Недопустимый знаменатель!"; exit(1); }
    else if( tnum == 0 )              // проверка числителя на 0
    { numerator=0; denominator = 1; return; }
// нахождение наибольшего общего делителя
    while(tnum !=0)
    {
        if( tnum < tden )            // если числитель больше знаменателя,
        { temp=tnum; tnum=tden; tden=temp; } //меняем их местами
        tnum = tnum - tden;          // вычитание
    }
    gcd = tden;                      // делим числитель и знаменатель на
    numerator = numerator / gcd;                 // полученный наибольший общий делитель
    denominator = denominator / gcd;
}
///////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
    fraction<char> f1, f2, f3, f4, f5, f6;
    f1.get();
    f2.get();
 
    f4 = f1 + f2;
    f4.lowterms();
    f4.display();
 
    f4 = f1 - f2;
    f4.lowterms();
    f4.display();
 
    f5 = f1 * f2;
    f5.lowterms();
    f5.display();
 
    f6 = f1 / f2;
    f6.lowterms();
    f6.display();
 
    return 0;
}
///////////////////////////////////////////////////////////
Ответ:
Сообщение от FliXis
Какой-то дичайше избыточный синтаксис у шаблонов, путаюсь постоянно.
На самом деле там все довольно логично.
Но видимо ты еще не поймал волну

Сообщение от FliXis
Осталось запомнить, что вот эти вот типы <char>, например, у методов отдельной реализации класса все равно писать надо.
Не надо это запоминать, надо разобраться где начинается class scope
Вопрос: Разработать шаблон функции, в которую передается массив и размер и возвращается индекс минимального элемента м

Разработать шаблон функции, в которую передается массив и размер и возвращается индекс минимального элемента массива.
Ответ:
Сообщение от hoggy
при работе с массивом, передавать его размер не обязательно.
поскольку эта информация итак известна времени компиляции.
Смотря где выделять память. Или я не прав?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
int main()
{
    size_t n;
    std::cin >> n;
 
    const int* ar = new int[n];
 
    for(size_t i = 0; i < n; ++i)
    {
        std::cout << ar[i] << std::endl;
    }
}
Вопрос: Удалить из массива нулевые элементы, передвинув на их место следующие элементы без нарушения порядка

ищу решение еще одной задачи =)

Задан массив действительных чисел. Удалить из массива нулевые элементы, передвинув на их место следующие элементы без нарушения порядка их следования. В результате должен получиться массив меньшего размера, не содержащий нулей. Заводить новый массив не разрешается.
Ответ: Здравствуйте! Извиняюсь что на С, но возможно чем то поможет:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void sort (int size, double *arr)
{  
   int n = 0, m = 0;
   for (int i=0; i<size; i++)//обходим массив один раз
   {
        if(arr[i]==0)n++;
        else
             if(n)
             {
                   m = i-n;
                   arr[m] = arr[i];
             }
         if(n==size)return;//если все нули выходим из функции
         for (int i=m+1; i < t; i++) arr[i]=0; // здесь проходим от последнего места копирования чтобы удалить все 0
    }
}
Вопрос: Как создать массив без размера?

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

как можно реализовать эту примитивнейшую задачу? .....не понимаю.
Ответ: Небольшая демка:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Linq;
 
internal sealed class Program {
  static void Main() {
    Int32[] arr = {};
    Console.WriteLine("Текущий размер массива : {0}", arr.Length);
    
    arr = (arr ?? Enumerable.Empty<Int32>()).Concat(Enumerable.Repeat(1, 1)).ToArray();
    Console.WriteLine("Размер массива после изменения : {0}", arr.Length);
    Console.Write("Элементы массива: ");
    foreach (Int32 i in arr) Console.Write(i);
    
    Array.Resize(ref arr, 5);
    Console.WriteLine("\nРазмер массива стал : {0}", arr.Length);
    Console.Write("Элементы массива: ");
    foreach (Int32 i in arr) Console.Write("{0} ", i);
    
    arr = arr.Where(i => i != 0 && i != 1).ToArray();
    Console.WriteLine("\nРазмер массива : {0}", arr.Length);
  }
}
Вопрос: Функция создаёт двумерный массив заданного размера

Функция создаёт двумерный массив заданного размера и инициализирует его по столбцам значениями из одномерного массива. Если в двумерном массиве больше элементов, чем в одномерном, то оставшиеся элементы в двумерном массиве инициализируются нулями. Если в одномерном массиве больше элементов, чем необходимо для инициализации двумерного массива, то лишние значения игнорируются.
Возвращаемое значение функции показывает факт игнорирования избыточных значений в массиве для инициализации.
Ответ: Марусенция,
Вот что у меня вышло
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
45
46
47
48
using System;
 
namespace Создание_двумерного_массива
{
    class Program
    {
        static int[,] Array_Create(int lines, int columns, int[] arr)
        {
            int[,] mass = new int[lines, columns];
            for (int i = 0; i < lines; i++)
            {
                for (int j = 0; j < columns; j++)
                {
                    if(arr.Length>i)
                        mass[i, j] = arr[i];
                }
            }
            return mass;
        }
 
        static void Main(string[] args)
        {
            int x;
            Console.Write("Введите размер исходного одномерного массива: ");
            x = Convert.ToInt32(Console.ReadLine());
            int[] arr = new int[x];
            for(int i = 0; i < x; i++)
            {
                Console.Write("Введите {0} элемент: ", i);
                arr[i] = Convert.ToInt32(Console.ReadLine());
            }
            Console.Write("Введите кол-во строк двумерного массива: ");
            int l = Convert.ToInt32(Console.ReadLine());
            Console.Write("Введите кол-во столбцов двумерного массива: ");
            int c = Convert.ToInt32(Console.ReadLine());
            int[,] myArray = Array_Create(l, c, arr);
            for(int i = 0; i < l; i++)
            {
                for (int j = 0; j < c; j++)
                {
                    Console.Write(" {0} ",myArray[i,j]);
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }
    }
}
Вопрос: Описать процедуру Hill(A, N), меняющую порядок элементов вещественного массива A размера N на следующий

Описать процедуру Hill(A, N), меняющую порядок элементов вещественного массива A размера N на следующий: наименьший элемент массива располагается на первом месте, наименьший из оставшихся элементов — на последнем, следующий по величине располагается на втором месте, следующий — на предпоследнем и т. д. (в результате график значений элементов будет напоминать холм). Массив A является входным и выходным параметром. С помощью этой функции преобразовать массивы A, B, C размера NA, NB, NC соответственно. ПАСКАЛЬ
Ответ: Puporev,
раз уж каждый элемент будет поставлен на свое место, то на каждом проходе двигать остаток массива нет смысла, достаточно просто менять минимальный и текущий элементы, что-то вроде:
Код Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure swapr(var a, b: Real);
var t: Real;
begin
  t:=a; a:=b; b:=t;
end;
 
procedure Hill(var a: mas; n: Integer);
var
  i, j, k: Integer;
begin
  for i:=1 to n div 2 do begin
    k:=i;                      { ищем минимальный ...}
    for j:=k+1 to n-i+1 do
      if a[j]<a[k] then k:=j;
    swapr(a[i],a[k]);          { меняем с текущим левым }
    k:=i+1;                    { ищем минимальный ... }
    for j:=k+1 to n-i+1 do
      if a[j]<a[k] then k:=j;
    swapr(a[n-i+1],a[k]);      { меняем с текущим правым }
  end;
end;
Вопрос: Дан вещественный массив А размером m×n. Определить k – количество «особых» элементов массива

Дан вещественный массив А размером m×n. Определить k – количество «особых» элементов массива А и вывести их на экран с указанием местоположения, считая элемент особым, если он больше суммы остальных элементов его столбца.
Ответ:
Сообщение от Puporev
как-то не так.
Немного ошибся, тогда

Код Delphi
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
var
  a: array of array of real;
 
procedure TForm1.Button1Click(Sender: TObject);
var i,j: integer;
function summ(n: integer): real;
var k: integer;
 begin result:=0;
  for k:=0 to High(a) do
   if n<=High(a[k]) then
    result := result+a[k,n];
 end;
begin
m1.Clear; m := StrToInt(le1.Text); n := StrToInt(e1.Text);
SetLength(a,m);
for i:=0 to m-1 do SetLength(a[i],n);
m1.Lines.Add('Генерируем матрицу размером ' + IntToStr(m) +
             ' на ' +IntToStr(n));
randomize;
for i:=0 to m-1 do
 for j:=0 to n-1 do
  a[i,j] := -5+10*random;
for i:=0 to m-1 do
 for j:=0 to n-1 do
  if a[i,j]>summ(j) then
   begin
    m1.Lines.Add('Сумма элементов столбца '+ FloatToStr(summ(j)));
    m1.Lines.Add('Уникальный элемент - ' + FloatToStr(a[i,j]));
    m1.Lines.Add('Позиция - [' + IntToStr(i) +
                 ', ' + IntToStr(j) + ']');
   end;
end;