Страницы

Поиск по вопросам

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

четверг, 9 апреля 2020 г.

Как прочитать с консоли строку неизвестной заранее длины не используя string?

#cpp #массивы #char #строки

                    
Я прекрасно понимаю, что можно использовать класс string и просто написать cin>>
 str; а затем получить количество элементов.
Я даже видел веселое решение при помощи malloc и realloc функций из C.
но все же, интересно, есть ведь какой-то способ при помощи средств C++, а конкретно
их потоков ввода и стандартных строк в виде массива символов прочитать из консоли строку,
не имея понятия о ее размере, получить впоследствии ее размер и положить в динамически
выделенный массив такого размера??
Вопрос не к спеху и не для какого-то задания, все чисто ради интереса, так что ваши
ответы, типа "не парься и пользуйся тем, что дают" также приветствуются )
    


Ответы

Ответ 1



cin >> str; запишет только до первого разделителя: http://ideone.com/Y5CJxD. Если под строкой понимается последовательность, которая заканчивается переводом строки ('\n'), то вам: std::getline() нужен: http://www.cplusplus.com/reference/string/string/getline/ А так, std::string это и так стандартное средство в C++. Если же хочется извратиться, то нужно читать блоками, проверять - есть ли перевод строки и агрегировать код, но лишнее нужно как-то хранить между вызовами. Либо, что проще, но медленнее - читать посимвольно, проверяя конец строки, например так: istream& getline(istream& is, char *&buffer) { std::istream::sentry s(is); if (s) { std::istreambuf_iterator it(is); std::istreambuf_iterator end; size_t size = 64; size_t grow = 64; size_t len = 0; buffer = new char[size]; while (it != end && *it != '\n') { if (len == (size - 1)) { buffer = buffer_realloc(buffer, size, size + grow); size += grow; } buffer[len++] = *it++; } buffer[len] = '\0'; } return is; } Здесь я не привожу функцию buffer_realloc() - она простая. Использовать как-то так: char *line = nullptr; while (getline(std::cin, line)) { if (line) { cout << line << endl; delete[] line; } } Либо вот вариант, где использует вектор: istream& getline(istream& is, vector &buffer) { std::istream::sentry s(is); if (s) { std::istreambuf_iterator it(is); std::istreambuf_iterator end; const size_t grow = 64; buffer.reserve(grow); while (it != end && *it != '\n') { if (buffer.size() == buffer.capacity() - 1) { buffer.reserve(buffer.size() + grow); } buffer.push_back(*it++); } buffer.push_back('\0'); } return is; } Использовать как-то так: vector line; while (getline(std::cin, line)) { if (!line.empty()) { cout << line.data() << endl; line.clear(); } } Тут реаллокация памяти ложится на плечи vector'а. От вас только почистить его (а можно и в гетлайн всунуть). Плюс бонусом сразу длинна строки за O(1): line.size() - 1 Вот законченные примеры: http://ideone.com/Huj4eQ http://ideone.com/CxNfg4 Но повторюсь: std::string стандартны для С++. Я слабо представляю условия, где есть потоки, но нет строк :)

Ответ 2



По сути, реализация cin выглядит так (игнорируя тот факт, что оба потока и строка шаблоны): std::istream& operator>> (std::istream& in, std::string& value) { std::istream::sentry cerberos(in); if (cerberos) { value.erase(); std::istreambuf_iterator it(in), end; if (it != end) { std::ctype const& ctype(std::use_facet >(in.getloc())); std::back_insert_iterator to(value); std::streamsize n(0), width(in.width()? in.width(): std::string::max_size()); for (; it != end && n != width && !ctype.is(std::ctype_base::space, *it); ++it, ++to) { *to = *it; } } } else { in.setstate(std::ios_base::failbit); } return in; } Выводы думаю вы можете сделать сами.

Ответ 3



Немного странный вопрос, т.к. если нужно сделать то же самое, что можно сделать с помощью std::string - следует хотя бы посмотреть реализацию operator>> для потока ввода и строкового аргумента. Основной смысл в том, что читаем посимвольно и посимвольно же добавляем. В итоге получим ещё и некоторое подобие реализации std::vector для символьного типа.

masm как сделать массив с изменяемой длиной

#массивы #ассемблер #arraylist #masm32

                    
Возможно ли изменить длинну массива (dd) и затем записать её в eax?
    


Ответы

Ответ 1



И нет, и да. Дело в том, что результат декларации dd - просто последовательность байт в бинарнике, которая статически грузится в память. Так что менять размер тут просто нечему. dd не является командой динамического выделения памяти - она просто статически помещает в бинарник нужную последовательность байт. Хотите выделить память - обратитесь к операционной системе и попросите. Через системный вызов.

суббота, 4 апреля 2020 г.

Ошибка при передаче массива в другое активити

#java #android #массивы #android_intent

                    
Есть одномерный массив

String [] mas=getResources().getStringArray(R.array.mas);


Его нужно  при клике по  button_3 передать в другое активити:

public void onClick(View v) {
       Intent intent3 = new Intent(this,Test_3.class);
        switch (v.getId()){
            case R.id.button_3:

                 intent3.putExtra("mas",mas);
                 startActivity(intent3);
                break;


В другом активити переданный массив получается так:

Bundle extras = getIntent().getExtras();
String[] mas3 = extras.getStringArray("mas");


Затем первый элемент массива отображается в текстовом поле:

int counter = 0;
  textView.setText(mas3[counter]);


В итоге после клика по кнопке переход на другое активити не осуществляется, выдает
ошибку, ссылаясь на последнюю строку

 textView.setText(mas3[counter]);


Подскажите, в чем ошибка?
    


Ответы

Ответ 1



Скорее всего вы ищите свой массив не там. Попробуйте его искать прямо в интенте, а не в его Bundle String[] mas3 = getIntent().getStringArray("mas"); Либо тогда уж помещать сначала массив в Bundle, Bundle в Intent и вытаскивать так, как вы сейчас вытаскиваете: Bundle bundle = new Bundle(); bundle.putStringArray("mas",mas); intent3.putExtras(bundle); startActivity(intent3); А ошибка возникает, видимо, из-за того, что при ненахождении значения в Bundle по умолчанию подставляется null

четверг, 2 апреля 2020 г.

Удалить элемент ассоциативного массива по ключу? [дубликат]

#php #массивы

                            
             
                
                    
                        
                            На этот вопрос уже даны ответы здесь:
                            
                        
                    
                
                        
                            PHP: Как сделать поиск на соответствие значению в массиве?
                                
                                    (2 ответа)
                                
                        
                Закрыт 2 года назад.
            
        

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

как пробовал делать:

$file3=file("ignore.txt");

print_r($sparam2[0]);
print_r($sparam2[2]);

for ($i = 0; $i ";
    unset($sparam2[$i][$keys4]);    
    }
}   


прикол в том, что даже строка echo $sparam2[$i][$keys4].""; ничего не выводит, echo
 $keys4 выводит нужный ключ.

вот результат вывода элементов (пример массива)

print_r($sparam2[0]);
 print_r($sparam2[2]);

Array
(
    [Название] => Название
    [Код Русского Света] => Код Русского Света
    [Артикул] => Артикул
    [Бренд] => Бренд
    [Цена] => Цена
    [Длина] => Длина
    [Источник света] => Источник света
    [Исполнение] => Исполнение
    [Аккумуляторный] => Аккумуляторный
    [Материал] => Материал
    [Тип батареи] => Тип батареи
    [Водонепроницаемый] => Водонепроницаемый
    [Цвет корпуса] => Цвет корпуса
    [Наличие на складе] => Наличие на складе
    [Ширина] => Ширина
    [Высота] => Высота
    [Тип светильника] => Тип светильника
    [Способ монтажа] => Способ монтажа
    [Тип цоколя] => Тип цоколя
    [Мощность лампы] => Мощность лампы
    [Класс защиты от поражения электрическим током] => Класс защиты от поражения
электрическим током
    [Материал корпуса] => Материал корпуса
)
Array
(
    [Название] => Фонарь S-LD043-B Silver Uniel UL-00000191
    [Код Русского Света] => 413391
    [Артикул] => UL-00000191
    [Бренд] => Uniel 
    [Цена] => 116.82
    [Длина] => 88 мм
    [Источник света] => Светодиод
    [Исполнение] => Карманный фонарь цилиндрической формы
    [Аккумуляторный] => Нет
    [Материал] => Алюминий
    [Тип батареи] => Мизинчиковый
    [Водонепроницаемый] => Да
    [Цвет корпуса] => Серебристый
    [Наличие на складе] => Штука
    [Ширина] => 
    [Высота] => 
    [Тип светильника] => 
    [Способ монтажа] => 
    [Тип цоколя] => 
    [Мощность лампы] => 
    [Класс защиты от поражения электрическим током] => 
    [Материал корпуса] => 
)


Для примера в файле игнора два ключа 
Материал
Тип батареи

Их нужно исключить из этого массива.
    


Ответы

Ответ 1



Немного не правильно. Как вы можете удалять елемент из массива и динамически проверять его размер? Нужный код должен быть примерно такой (если конечно данные из файла валидные, а то вы file используете без параметров...): $file3=file("ignore.txt"); print_r($sparam2[0]); print_r($sparam2[2]); // индекс 2 ??? это не ошибка? $nof_params = count($sparam2); $file3_count = count($file3); $array_to_delete = array(); //создаем массив елементов для удаления for ($i = 0; $i <$nof_params; $i++) { for ($j = 0; $j <$file3_count; $j++) { $keys4=$file3[$j]; echo $sparam2[$i][$keys4]."
"; array_push($array_to_delete, array($i, trim($keys4))); } } for($i = 0; $i < count($array_to_delete); $i++) { $ii = $array_to_delete[$i][0]; $keys4 = $array_to_delete[$i][1]; unset($sparam2[$ii][$keys4]); }

Ответ 2



Неоднократно уже поднимались тут вопросы связанные с функцией file(). Если ее используют без настройки вторым параметром, получают не то, что хотели. $file3 = file("ignore.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); где FILE_IGNORE_NEW_LINES - Не добавлять новую строку к концу каждого элемента массива FILE_SKIP_EMPTY_LINES - Пропускать пустые строки

Пройтись несколько раз по массиву и просчитать ходы

#массивы #алгоритм

                    
Добрый вечер, нужна подсказка для решения задачки:
Есть поле(массив) 3 на 3:

1 2 3
4 5 6
7 8 9


К примеру я выбираю поле 7 и мне надо от 7 сделать 8 шагов вверх(или же вниз,влево,вправо)
то есть если это вверх то будет такой ход: 4,1,8,5,2,9,6,3
если рассматривать ситуацию от 7 вправо то будет так: 8,9,1,2,3,4,5,6 ну и тд.
Очень буду признателен за любой совет по тому как это реализовать, реализовывать
буду на PHP но думаю здесь это не важно, так как нужен сам алгоритм решение можно даже
на словах 
    


Ответы

Ответ 1



(Как криворожанин жителю Днепропетровской области.) Вот одна из четырех функций. Три остальные будут отличаться направлениями движения (++/--), очередностью изменений i и j и проверками (не на длину, а на ноль). var arr = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; function goRight(arr, i, j, count) { var rows = arr.length; var cols = arr[0].length; var result = []; for (var k = 0; k < count; k++) { j++; if (j >= cols) { j = 0; i++; if (i >= rows) { i = 0; } } result.push(arr[i][j]); } return result; } console.log(goRight(arr, 2, 0, 8));

понедельник, 30 марта 2020 г.

Сортировка объектов классов в разные массивы

#java #массивы #arraylist


Есть Class1 и Class2. И есть класс, который должен создавать массивы из этих классов.
Если передавать в конструктор объект неизвестного класса и там делать проверку, то
возникает ошибка. Как это сделать?
Класс для создания массива:

 package com.company;

 import java.util.ArrayList;

public class Generic {
 private ArrayList arr1 = new ArrayList<>();
 private ArrayList arr2 = new ArrayList<>();

 Generic(Object obj)
 {
     if (obj instanceof Class1)
     {
         this.arr1.add(obj); // Здесь ошибка возникает, хотя делаем проверку
     }
 }
}

    


Ответы

Ответ 1



Следует явно привести тип переменной к классу: import java.util.ArrayList; public class Generic { private ArrayList arr1 = new ArrayList<>(); private ArrayList arr2 = new ArrayList<>(); Generic(Object obj) { if (obj instanceof Class1) { this.arr1.add((Class1)obj); // Здесь добавляем приведение типа } } }

воскресенье, 29 марта 2020 г.

Выбрать только уникальные массивы (и с большей длинной) из многомерного массива

#php #массивы


Пример массива:

array(
    0 => array(
        'alias' => 'test',
        'title' => 'stack',
        'content' => 'overflow',
        'year' => 2019,
        'test' => null
    ),

    1 => array(
        'alias' => null,
        'title' => 'stack',
        'content' => 'overflow',
        'year' => null,
        'test' => null
    ),

    2 => array(
        'alias' => 'else',
        'title' => 'demo',
        'content' => 'stack_overflow',
        'year' => 2020,
    )
);


Уникальным ключом является title, выходит массивы с индексами 0, 1, являются дублями,
таких массивов может быть очень много...

Мне нужно оставить только тот массив в котором меньше всего значений null, то есть
в данном случае массив с индексом 1 нужно удалить, так-как это дубль массива с индексом
0 и т.д. Таких дублей может быть разное количество.

Думал сделать что-то подобное:

if(strlen(serialize($array))) {
    //Пишем массив который длиннее 
}


Но не могу придумать как найти совпадения...
    


Ответы

Ответ 1



В итоге написал такую функцию: public function removeArrayDuplicates($array, $index_key) { $result = array_reverse( array_values( array_column( array_reverse($array), null, $index_key) ) ); return $result; } var_dump(removeArrayDuplicates($array, $title)); Получаю массивы без дублей и с нужными значениями. UPDATE: Всё таки не с нужными значениями. Данная функция не сработала как ожидалось поэтому нагородил другую. Эта точно работает как нужно. Может кому то будет полезно, либо сможете улучшить мой ответ. function removeArrayDuplicates($array, $search_key) { $stored_duplicates = array(); $max_array_length = null; $current_array = null; $result = array(); foreach($array as $item) { $stored_duplicates[$item[$search_key]][] = $item; } foreach($stored_duplicates as $arrays) { foreach($arrays as $item) { if(count($arrays) > 1) { $array_length = strlen(serialize($item)); if($array_length > $max_array_length) { $max_array_length = $array_length; $current_array = $item; } } else { $result[] = $item; } } if($current_array) { $result[] = $current_array; $max_array_length = null; $current_array = null; } } return $result; }

суббота, 21 марта 2020 г.

Удалить пустые элементы массива

#массивы #lua


Есть массив ITEMS(item1=1,item2=2,item4=4,"",item10=10,"",item16=16)

Вывожу его содержимое 
print("массив ITEMS:",table.concat (ITEMS, ", "))

Получаю: 
1, 2, 4, , 10, , 16

Как можно удалить пустые строки отсюда?
    


Ответы

Ответ 1



Ответ @Ainar-G работает некорректно для массивов, где два пустых элемента идут подряд. Есть два способа обойти это: Сперва записать элементы для удаления, а после уже удалить их: local a = { "a", "b", "", "c", "", "", "d" } local function cleanupArray(arr, valtodel) local todelete = {} for k, v in ipairs(arr) do if v == valtodel then todelete[#todelete+1] = k end end for k, v in ipairs(todelete) do table.remove(arr, v-k+1) end return arr end cleanupArray(a, "") print(table.concat(a, ", ")) Try it online! Не менять индекс, если мы удалили элемент: local a = { "a", "b", "", "c", "", "", "d" } local function cleanupArray(arr, valtodel) for i = 1, #arr do ::begin:: local v = arr[i] if v == nil then return end if v == valtodel then table.remove(arr, i) goto begin end end end cleanupArray(a, "") print(table.concat(a, ", "))

пятница, 20 марта 2020 г.

Как выделить память для большого двумерного массива в Си?

#c #массивы #память


Я работаю с большим двумерным массивом.
В случае, когда он размером 30 x 200, все считается. При больших объемах программа
вылетает... Мне посоветовали использовать memset(), но что-то не особо помогает...
Может быть у вас есть какие идеи?
#include 
#include 
#include 
#include 

double **B;

int main (int argc, char *argv[])
{ 
    int N, n_A;

    N = 32;
    n_A = 350; /* если сделать n_A = 200, то все работает */
    B = (double **)malloc(N * sizeof(double *));

    for(i = 0; i < N; i++)
    {
        B[i] = (double *)malloc(n_A * sizeof(double));
        memset(B[i], 0, n_A * sizeof(double));
    }

    free(B);

    return 0;
}
    


Ответы

Ответ 1



В целом код правильный, но нужно добавить проверку при выделении памяти: это необходимо, потому что памяти может просто не хватать, и в этом случае программа будет падать, потому что будет происходить запись в несуществующую память. То есть всякий раз, когда происходит вызов malloc, необходимо проверить, что возвращаемое значение не равно NULL. B = (double **)malloc(N * sizeof(double *)); /* Проверить, что память выделена */ if (B != NULL) { for(i = 0; i < N; i++) { B[i] = (double *)malloc(n_A * sizeof(double)); /* Проверить, что память выделена */ if (B[i] != NULL) { memset(B[i], 0, n_A * sizeof(double)); free(B[i]); } } free(B); } Кроме того, нужно не забывать освобождать память, выделяемую malloc внутри цикла, иначе будут утечки.

Ответ 2



Вот это все можно сделать одной строкой double * B; B = (double *) calloc (N * n_A, sizeof(double)); free (B); Вместо вызова кучи функций вы вызываете одну, которая сразу выделяет память под весь массив данных и обнуляет ее. Доступ к данным осуществляется по формуле double a; a = *(B + i * n_A + j); где i - номер строки, j - номер столбца

Ответ 3



При больших объемах программа вылетает... Локальный буфер(точнее размер стекового фрейма) не должен иметь размер больший одной страницы. Иначе произойдёт обращение за пределы сторожевой страницы стека, расширен он не будет и возникнет исключение.

четверг, 19 марта 2020 г.

Как на Java параллельно сложить два массива?

#java #массивы #распараллеливание


Например, есть два огромных (длина 2-3 млн.) массива float[] или double[] без разницы.
Нужно их очень быстро сложить. Как это сделать? Есть ли какие-нибудь библиотеки для
этого?     


Ответы

Ответ 1



Я про 8 Java и LambdaJ написал скорее для общего ознакомления и для ответа на коммент про аналоги LINQ. Если отвечать в рамках вопроса, то ни LINQ, ни Java 8 и ни LambdaJ не является быстрым решением вопрооса сложения (с точки зрения производительности). Сложение слишком простая операция и накладные расходы на вского рода вкусности, вроде функционального стиля, будут слишком велики. Согласно докам по LambdaJ она в два раза медленее в среднем чем просто циклы. (В некоторых местах доходит до 4х раз). Новая Java все еще не в релизе, и пользоваться ей в продакшене не стоит. Остается только ручная многопоточность (мне кажется что 2-3 миллиона это не такие уж и огромные данные для операции сложения). На своем дряхленьком нетбуке я смог ускоритсья на двух тредах. Выложил код на гитхаб, надеюсь ктонить попробует и выложит информацию с нормального железа. Насчет использования с++ и SSE, следующий код: for (int i = 0; i < a.length; i++) c[i] = a[i] + b[i]; Компилится в SSE инструкции JIT'ом. Насколько будет выйгрыш, если вручную написать на SSE - не знаю. Возможно не стоит заморачиваться с нативным кодом.

Ответ 2



Это ответ не по теме, но возможно, другим участникам сайта он пригодится в будущем. В .NET PLINQ умеет самостоятельно разбить задание на нужное количество потоков (определяемое количеством процессоров/ядер на хосте) и выполнить операцию параллельно по частям. int length = Math.Min(arr1.Length, arr2.Length); double[] results = ParallelEnumerable.Range(0, length).AsOrdered() .Select(index => arr1[index] + arr2[index]) .ToArray(); Update: Как верно заметил @IronVbif, «наивный» PLINQ медленнее цикла, выполненного вручную. Однако на этот случай у .NET есть специальная перегрузка: int length = Math.Min(arr1.Length, arr2.Length); double[] results = new double[length]; var rangePartitioner = Partitioner.Create(0, length); Parallel.ForEach(rangePartitioner, (range, loopState) => { for (int i = range.Item1; i < range.Item2; i++) result[i] = arr1[i] + arr2[i]; }); (выполняется существенно быстрее, чем простое сложение).

вторник, 17 марта 2020 г.

Массив из разных типов [дубликат]

#массивы #хранилище #cpp


        
             
                
                    
                        
                            На этот вопрос уже даны ответы здесь:
                            
                        
                    
                
                        
                            Можно ли хранить объекты разных классов (производных
одного абстрактного класса) в одном массиве или списке?
                                
                                    (3 ответа)
                                
                        
                                Закрыт 2 года назад.
            
                    
Существует ли возможность в c++ сделать массив из разных типов? Или какое-то хранилище-переменную,
в которой можно хранить разнотиповые вещи? У меня есть несколько структур, и массив,
который будет динамически изменяться, и вот хотелось бы как-то добавлять в него значения
разных типов.    


Ответы

Ответ 1



Предложу ещё третий, более с++ способ. Какие разрообразные объекты у Вас не были бы, все равно у них есть общий предок (да, void* - это вырожденный случай и обычно говорит либо о сильной преждевременной оптимизации или просто незнания ООП). Итак, первое - нужно написать базовый класс. От него наследуются другие классы для разных данных. Даже если нужно хранить строку и число. Так как есть базовый класс, то можно написать std::vector vec; и уже есть массив объектов. Пусть нужно вывести всех их на печать. Для этого для каждого наследника нужно определить метод вида friend ostream& operator<<(ostream& os, const YourType& dt); И все, можно будет выводить на печать таким кодом for (int i = 0; i < vec.size(); i++) std::cout << vec[i] << std::endl; Очень просто. Но пусть нужно сохранять объекты и загружать с файла. Добавим в базовый тип виртуальный метод "getObjectType", "getObjectSize", "saveToStream" и "loadFromStream". Каждый наследник должен будет их определить. Теперь при сохранении где то так fstream fs; fs.write(vec.size(), sizeof(size_type)); for (int i = 0; i < vec.size(); i++) { int t = vec[i].getObjectType(); size_t s = vec[i].getObjectSize(); fs.write(t, sizeof(t)); fs.write(s, sizeof(s)); vec[i].writeToStream(fs); } красиво? А вот с загрузкой немного сложнее. Нужно будет хранить массив соответствий "тип объекта"->"ссылка на конструктор". Но при небольшом кол-ве объектов, можно и if-else или switch size_type c; fs.read(c, sizeof(c)); for (int i = 0; i < c; i++) { int t; size_t s; BaseObj* bb; fs.read(t, sizeof(t)); fs.read(s, sizeof(s)); switch (t) { case 1: bb = new IntObject(); break; case 2: bb = new StringObject(); break; //.... default: // unknown object, can skip fs.seekg (s, fs.beg); break; } bb->loadFromStream(fs, s); } upd Главное не забывать делать методы виртуальными, а также сделать виртуальным деструктор. Конечно, если классы не будут иметь общего предка, то все это работать не будет.

Ответ 2



да такое можно сделать, но если вам это понадобилось то скорее всего имеет смысл переделать архитектуру программы. реализовать это можно например в виде велосипеда над указателями Void. или гораздо лучший вариант это использовать boost boost::Any вот тут можно почитать в любом случае, лучше сначала подумать над архитектурой. UPD собственно пример изменения архитектуры привёл KoVadim...

Извлечение случайного значения из массива в Visual Basic 2010

#массивы #php #visual_basic


Начал изучать Visual Basic и столкнулся с проблемой. Нужно сделать символьный массив
и получить случайное значение из этого массива в переменную. Я только начал изучать
Visual Basic, но на php это бы выглядело как:
$mass = array("lalka", "fsdfsd546", "heyt");//массив с названием $mass
$per = array_rand($mass, 1);//Извлекаю из этого массива одно значение в переменную
echo ($per);//Вывожу сообщение

Прошу написать как этот код будет выглядеть в Visual Basic.    


Ответы

Ответ 1



Поймите: Visual Basic и VB.NET - практически одно и тоже (синтаксис очень схож), отличие в том, что VB.NET[Visual Basic .NET] работает на платформе .NET Framework. Вы просите код на "Visual Basic 2010". Ппрактически, это он и есть, этот код будет работать и в "Visual Basic 2008", "Visual Basic 2005", и даже в "VS Express 2013 for Desktop"(который содержит Visual Basic). Почитайте спецификацию и определение Visual Basic 6/VB.NET/.NET Framework. Повторюсь, лучше учите C# (тоже на платформе .NET Framework)! Сама функция: Public Function RandomWord() ' Случайное число Dim rnd As New Random() ' Ваш массив: Dim massive() As String = {"lalka", "fsdfsd546", "heyt"} ' Случайное число, ограниченное количеством строк массива Dim random As Integer = rnd.Next(massive.Length) ' Вернуть результат: Return massive(random) End Function Затем используйте функцию, функция возвращает string: Dim randomword As String = RandomWord() И делайте вывод при помощи MessageBox.Show(randomword), Console.WriteLine(randomword) или другими

Ответ 2



Вариант Sub RndStr() Dim ArrStr() Dim sStr As String ArrStr = Array("lalka", "fsdfsd546", "heyt") Randomize sStr = ArrStr(Int((UBound(ArrStr) + 1) * Rnd)) MsgBox sStr End Sub

Как в Atmel Studio 6 разместить массив во flash памяти?

#c #массивы #avr_gcc #atmel_studio #flash_память


Например, есть массив:
unsigned int tabz[] = {64, 128, 256, 512, 1024, 2048, 4096};

В CodeVisionAVR, чтобы разместить этот массив во flash, надо написать так:
flash unsigned int tabz[] = {64, 128, 256, 512, 1024, 2048, 4096};

В Atmel Studio 6 так нельзя.
Как в Atmel Studio 6 разместить массив во flash памяти?    


Ответы

Ответ 1



Для flash-памяти необходимо объявлять так: const unsigned char Scena[4] PROGMEM = {1,2,3,4} Обязательно указывать const, иначе пихает в ОЗУ!

Ответ 2



Пример для AVR GNU: #include #include uint8_t string[12] PROGMEM = {"hello world!"}; int main(void) { UDR0 = pgm_read_byte(&string[10]); }

воскресенье, 15 марта 2020 г.

Алгоритм поиска в массиве двух максимальных значений

#алгоритм #массивы #любой_язык


В результате нужно получить индексы ячеек массива с максимальными значениями.

Например, для массива arr[4, 50, 11, 20] это будут 1 и 3 (arr[1], arr[3]) - индексы
максимальных значений.
    


Ответы

Ответ 1



Ну, почему бы не пробежаться по массиву и держать текущие k наибольших значений? Вот вам псевдокод: list maximalK = empty // инвариант: maximalK содержит отсортированный список наибольших // k из всех просмотренных элементов foreach e in sourceList p = position of e in maximalK // (binary search) if (p >= k) continue insert e into maximalK at position p if maximalK.size > k remove last from maximalK Заметьте, что при k == sourceList.size вы получаете просто алгоритм сортировки (бинарными) вставками. Временная сложность: O(n * k) (n — размер списка), за счёт сдвига при вставке. (Используя sorted map для maximalK, можно уменьшить до O(n * log k).)

array.sort() не понимает украинские буквы Є и І

#javascript #массивы


Имеется простой массив имен на украинском языке, в котором имена сортируются в алфавитном
порядке например:




Все сортируется отлично за исключением имен которые начинаются с украинских букв
Є и І — такие имена почему то ставит первыми. Как сделать чтобы они были на нужном месте?
    


Ответы

Ответ 1



Нашел ответ на англоязычной версии StackOverflow:

Ответ 2



Сортировка выполняется на основании кодов символов с учётом регистра. Для изменения порядка сортировки надо написать свой компаратор. Как вариант, сложить алфавит в отдельную строку, приводить аргументы к нужному регистру и сравнивать индексы в искомой строке. Естественно, этот способ медленный и имеет смысл его как-то улучшить, но я не знаю украинский алфавит. Если выполнить на странице википедии такой код var res = {}; document.querySelector("#toc ~ table").textContent.match(/(.)(?= \1)/gi).map(function(x,i) { res[x]=i+1 }) console.log(JSON.stringify(res)) То получится такой объект: {"А":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} После приведения строки к верхнему регистру, для двух букв-ключей надо сравнивать значения.

Свой List из array

#cpp #массивы #классы #указатели #список


Пытаюсь создать свой list из array

есть структура 

template 
struct Node {
    T data;
    Node* next; 
};


собственно функция 

template 
Node* arrayToList(const T tab[], size_t size){

Node *node = new Node;
for(int i=0;idata = tab[i];
node->next = new Node;
}
}


в main 

    int tabi[] = {2,1,4,3,6,5,7,8};
size_t sizei = sizeof(tabi)/sizeof(tabi[0]);
Node *listAi = arrayToList(tabi,sizei);


так вот проблема в том что не могу править созданный экземпляр Node тут node->next
= new Node; я создаю экземпляр , а как в него значение из массива занести ?  
    


Ответы

Ответ 1



Не понятно, в чем состоит ваша проблема Поэтому я предложу код, который позволяет заполнить список элементами массива. Надеюсь, что если это не то, что вам нужно, то вы об этом сообщите мне в своем комментарии к ответу. Вот демонстрационная программа #include template struct Node { T data; Node *next; }; template Node * arrayToList( const T a[], size_t n ) { Node *head = nullptr; Node **current = &head; for ( size_t i = 0; i < n; i++, current = &( *current )->next ) { *current = new Node { a[i], nullptr }; } return head; } template void displayList( Node *head ) { for ( ; head; head = head->next ) std::cout << head->data << ' '; } int main() { int a[] = { 2, 1, 4, 3, 6, 5, 7, 8 }; const size_t N = sizeof( a ) / sizeof( *a ); for ( int x : a ) std::cout << x << ' '; std::cout << std::endl; Node *list = arrayToList( a, N ); displayList( list ); std::cout << std::endl; } Ее вывод на консоль: 2 1 4 3 6 5 7 8 2 1 4 3 6 5 7 8 Если ваш компилятор не поддерживает список инициализации для оператора new, то предложение *current = new Node { a[i], nullptr }; вы можете заменить на следующие предложения *current = new Node; ( *current )->data = a[i]; ( *current )->next = nullptr; Либо вы можете написать для класса Node конструктор, чтобы можно было бы опять записать все в одну строчку, как, например *current = new Node( a[i], nullptr );

понедельник, 9 марта 2020 г.

Как переустановить Ubuntu и не потерять данные на RAID 1 (mdadm)?

#linux #массивы #ubuntu #debian #raid


Добрый день, Имеется программный raid1, необходимо переустановить линукс. Не будут
ли форматированы диски при создании нового рейда?
    


Ответы

Ответ 1



Бекап важный файлов никогда не мешает. Загрузитесь с LiveCD/LiveUSB. Если Файловая система видна корректно, то значит все получится. Если у Вас разбито правильно (то есть /home и / (корень) лежат в отдельных разделах), то просто отформатируйте корень и устанавливайте систему (при этом лучше поискать там возвожность расширенной установки). Если же система поставленна по виндовому (то есть, все в один раздел), то загрузившись с лайва, поудаляйте все, кроме /home и устанавливайте систему, при этом, не забудьте снять галочки "форматировать раздел".

Ответ 2



Я надеюсь, что ОС установлена на отдельном жестком диске, не имеющем отношения к массиву. Этот диск можно отформатировать и поставить новую ОС. После переустановки ОС запустите поиск созданных ранее массивов: mdadm --assemble --scan Так можно посмотреть текущее состояние массива: cat /proc/mdstat Создайте конфиг-файл для массива: mdadm --detail --scan --verbose > /etc/mdadm.conf Создайте точку монтирования для массива: mkdir /home/myRAID Для того, чтобы массив загружался при каждой загрузке ОС, Добавим строчку в /etc/fstab: /dev/md0 /home/myRAID ext4 defaults 0 0 Эта запись подразумевает, что адрес устройства вашего массива /dev/md0 (уточните это, сделайте ls /dev/md*); а так же, что у вас файловая система ext4. Если у вас другая, впишите другое соответствующее значение (например, ext3, NTFS, итд.) Далее даны стандартные параметры, подробне можно прочитать тут. Монтируем массив: mount -a Эта команда монтирует всё, что ещё не примонтировано в системе, но указано в /etc/fstab. p.s. так же, посмотреть на текущее состояние массива можно командой: mdadm -D /dev/md0 Перед переустановкой ОС убедитесь, что с вашим массивом всё в порядке.

воскресенье, 8 марта 2020 г.

Как распределить числа из массива js

#javascript #массивы #сортировка


Задача такая:

var streak = {
  min: '',
  max: '',
  length: '',
  series: []
}

var allStreaks = []


У меня есть массив чисел:

var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9]


Мне нужно распределить их по массивам чтобы в нем были эти числа в порядке возрастания,
и записать все это в таком формате:

[{
  min: 19,
  max: 22,
  length: 4,
  series: [19, 20, 21, 22]
}, {
  min: 17,
  max: 19,
  length: 3,
  series: [17, 18, 19]
}, {
  min: 7,
  max: 9,
  length: 3,
  series: [7, 8, 9]
}]


В исходном массиве числа идут в том порядке в котором они мне нужны будут (как будто
если бы эти числа шли по датам - одно число - один день) Мне нужно отловить сколько
"дней" эти числа увеличивались, с какого числа началось и на каком остановилось и потом
все сначала. Первые 4 числа массива arr (19 20 21 22) должны создать объект в котором
будет записано минимальное число (19), максимальное число (22), сколько всего чисел
было записано (4) и собственно сам массив этих чисел [19, 20, 21, 22]. Точно так же
со вторым возрастающим стриком с 17 до 19 итд
        Числа в исходном массиве абсолютно рандомные и нужно отследить эту череду
увеличений и как только встречается число меньше предыдущего начать новый массив

На данный момент делаю так:

for (var i = 0; i < arr.length-1; i++) {
  if (arr[i] < arr[i+1]) {
    streak.series.push(arr[i])
  } else {
    streak.series.push(arr[i]) //Сохранит последний элемент первого стрика
    break;
  } 
}


Так я успешно получаю первый стрик, однако если мне надо продолжить, то возникают
трудности: 

for (var i = 0; i < arr.length-1; i++) {
  if (arr[i] < arr[i+1]) {
    streak.series.push(arr[i])
  } else if ((arr[i] > arr[i-1]) && (arr[i] > arr[i+1])) {
    streak.series.push(arr[i]) // Это ловит и записывает последний элемент первого
стрика, получается steak.series = [19,20,21,22]
    // но он на этом не останавливается и продолжает записывать все числа исходного
массива
    // так как они потом подходят под первый if (arr[i] < arr[i+1])
    // и в результате у меня просто переписывается весь исходный массив
  } else {continue;} 
}

    


Ответы

Ответ 1



var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9] var resArr = []; var min = max = length = 0; var tempArr = []; var prev = 0; arr.forEach(function(item) { if(prev > item && prev){ resArr.push({'min':min,'max':max,'length':length, 'series':tempArr}); min = 0; max = 0; tempArr = []; length = 0; } if(item > max) max = item; if(item < min || min == 0) min = item; length++; tempArr.push(item); prev = item; }); resArr.push({'min':min,'max':max,'length':length, 'series':tempArr}); console.log(resArr);

Ответ 2



var allStreaks = []; var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9]; var prevMaxPos = 0; doWork(); console.log(allStreaks); // функции работы и заноса в итоговый массив function doWork() { for (var i = 1; i < arr.length; ++i) { if (arr[i] < arr[i - 1]) { allStreaks.push(setStreak(arr.slice(prevMaxPos, i))); prevMaxPos = i; } } if (arr.slice(prevMaxPos).length > 0) allStreaks.push(setStreak(arr.slice(prevMaxPos))); } function setStreak(arr) { return streak = { min: arr[0], max: arr[arr.length - 1], length: arr.length, series: arr } }

Ответ 3



решение в стиле минимализм ... var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9]; function go(d) { var a; return d.reduce(function(c, b) { a && b == a.max + 1 ? (a.max = b, a.length++, a.series.push(b)) : (a = { min: b, max: b, length: 1, series: [b] }, c.push(a)); return c }, []) }; console.log(go(arr))

Ответ 4



ещё одно минималистическое, но читаемое решение var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9], distribute = function(arr) { var out = [], series = [], i = 1; while (i < arr.length + 1) { series.push( arr[i-1] ); if (! (arr[i-1] < arr[i++])) { out.push({ min: series[0], max: series[series.length-1], length: series.length, series: series.slice() }); series = []; } } return out; } console.log( distribute(arr) );

Алгоритм Сапера на си шарп

#c_sharp #массивы


Написал консольное приложение сапер, но появились проблемы с реализацией. Мой алгоритм
таков: есть массивы, один для показа клеток в консоли, в другом содержаться расположения
мин(9-мина,0-8  соответственно кол-во мин рядом). При выборе одной из клеток, если
клетка содержит 0, то проверяются все соседние клетки по порядку, а в массиве для показа
этот ноль становится видимым, если те клетки содержат 0,то снова выполняется этот рекурсивный
проход по клеткам и отображение в массиве для показа. Так вот, в случае если выбрана
одна из клеток и она ноль, в клетке слева и сверху содержатся единицы,а в клетке сверху-слева
находится ноль, то по идее этот ноль не должен отображаться,потому что к нему нет прямого
доступа(то есть,с любых сторон кроме диагональных)Как мне реализовать это?
    


Ответы

Ответ 1



Очень просто. При открытии 0-клетки ищите 0-соседей не по диагонали, а только сверху, снизу, слева и справа.

суббота, 7 марта 2020 г.

C# и .Net. Почему пользовательская функция Swap работает неправильно?

#c_sharp #массивы #net


Добрый вечер!

Задача следующая: Дан так называемый ступенчатый(зубчатый) массив целых чисел
 int[][] matrix. Для определенности, пусть массив будет размерности 5:

    int[][] matrix = new int[5][]
    {   
        new int[10] {5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
        new int[4] {2, 2, 2, 2},
        new int[5] {20, 20, 20, 20, 20},
        new int[3] {1, 2, 1},
        new int[4] { 2, 3, 4, 5 }
    }


Необходимо поменять две любые строки между собой. Для этого я написал следующую функцию
Swap:

    /// 
    /// Swapping matrix strings
    /// 
    /// first string
    /// second string
    private static void SwapMatrixStrings(int[] a, int[] b)
    {
        int[] tmp = a;
        a = b;
        b = tmp;
    }


Казалось бы, что переменные типа int[] - это переменные ссылочного типа. Но почему
тогда после вызова:

    Swap(matrix[0], matrix[1]);


массив int[4] {2, 2, 2, 2} не поменялся местами с массивом int[10] {5, 5, 5, 5, 5,
5, 5, 5, 5, 5} в массиве matrix?

UPD. Если в методе передавать параметры по ссылке с помощью ключевого слова ref,
то метод работает так, как надо.
    


Ответы

Ответ 1



Потому что она обменивает локальные переменные, а не параметры. Параметры в C# передаются по значению, если не указано ref или out. Это относится и к параметрам ссылочного типа, при этом по значению передаётся ссылка. Попробуйте указать в сигнатуре функции ref. Что происходит в вашем коде? В функцию SwapMatrixStrings вы передали ссылочные выражения matrix[0] и matrix[1] в качестве аргументов. То есть, параметры a и b получили значение, совпадающее с matrix[0] и matrix[1] (то есть, их копии). В результате выполнения вашей функции, значения a и b поменялись местами. Но это никак не затрагивает исходные величины matrix[0] и matrix[1].