Как найти наибольшее число в файле

The file looks like this:

1, a b
2, c d
3, e f

my current code

b = open('file.txt', 'r')

c = b.readlines()
regels = len(c)

print(regels)

I got the numbers of lines but still need biggest number + on which line it is.

asked Sep 20, 2016 at 18:27

54m's user avatar

2

So you are just looking to find the biggest number in the first column of the file? This should help

b = open('file.txt', 'r')

c = b.readlines()
regels = len(c)

print(regels)

max = 0
for line in b.readlines():
  num = int(line.split(",")[0])
  if (max < num):
    max = num 


print(max)
# Close file
b.close()

answered Sep 20, 2016 at 18:37

Ali's user avatar

AliAli

6331 gold badge9 silver badges20 bronze badges

5

This is how I’d go about doing it.

max_num = 0
with open('file.txt', 'r') as data: # use the with context so that the file closes gracefully
  for line in data.readlines(): # read the lines as a generator to be nice to my memory
    try:
      val = int(line.split(",")[0])
    except ValueError: # just incase the text file is not formatted like your example
      val = 0
    if val > max_num: # logic
      max_num = val

print max_num #result

answered Sep 20, 2016 at 18:43

reticentroot's user avatar

reticentrootreticentroot

3,6022 gold badges22 silver badges39 bronze badges

You need loop over each line in file, parse each line and find the largest number.

I do not quite understand how the numbers are stored in your file. Just assuming that in each line, the first field are numeric and separate with others (non-numeric) by ','. And I assume all numbers are integer.

ln = 0
maxln = 0
maxn = 0
with open(filename, 'r') as f:
    line = f.next()
    if line:
       ln = 1
       maxln = 1
       maxn = int(line.split(",")[0].strip())
    else:
       raise Exception('Empty content')
    for line in f:
        ln += 1
        cur = int(line.split(",")[0].strip())
        if cur > maxn:
            maxn = cur
            maxln = ln

ln is used to record current line number, maxn is used to record current maximum number, and maxln is used to record current maximum number location.

One thing you need to do is fetch the first line to initialize these variables.

answered Sep 20, 2016 at 18:47

rojeeer's user avatar

rojeeerrojeeer

1,9811 gold badge11 silver badges13 bronze badges

None of the answers give you the line of the max number so I’ll post some quick code and refine later

max_num = 0
line_count = 0
with open('file.txt', 'r') as infile:
    for line in infile:
        number = int(line.split(',')[0])
        if number > max_num:
             max_num = number
             line_num = line_count
        line_count += 1
print (max_num)
print (line_num)

answered Sep 20, 2016 at 18:51

roganjosh's user avatar

roganjoshroganjosh

12.5k4 gold badges29 silver badges46 bronze badges

3

  • Read line
  • Split it on basis of comma
  • Append first element to temp list.

Once complete reading of file is done,

  • To get maximum number, just use max function on temp list.
  • Since file is read line by line sequentially and appending number from line to temp list, to get line number on which maximum number is present, just find the index of max number in temp list and increment it by one since list index starts with zero.

P.S : Check last three print statements

Code:

num_list = []
with open('master.csv','r')as fh:
    for line in fh.readlines():
        num_list.append(int((line.split(','))[0]))

print num_list
print "Max number is -" ,max(num_list)
print "Line number is - ", (num_list.index(max(num_list)))+1

Output:

C:Usersdinesh_pundkarDesktop>python c.py
[1, 2, 3]
Max number is - 3
Line number is -  3

C:Usersdinesh_pundkarDesktop>

answered Sep 20, 2016 at 18:42

Dinesh Pundkar's user avatar

Dinesh PundkarDinesh Pundkar

4,1301 gold badge22 silver badges36 bronze badges

4

Iterate through the file and keep track of the highest number you’ve seen and the line you found it on. Just replace this with the new number and new line number when you see a bigger one.

b = open('file.txt', 'r')
max = -1
lineNum = -1
line = b.readline()
index = 0
while(line):
    index+=1
    newNum = line[0]
    if(newNum>max):
        max = newNum
        lineNum = index
    line = b.readline()
print lineNum,max,index

max is your highest number, lineNum is where it was, and index is the number of lines in the file

answered Sep 20, 2016 at 18:42

SilentLupin's user avatar

SilentLupinSilentLupin

65810 silver badges16 bronze badges

2

0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

1

Найти наибольшее значение из чисел записанных в файл

17.08.2015, 11:12. Показов 8584. Ответов 17


Студворк — интернет-сервис помощи студентам

В текстовом файле записана непустая последовательность вещественных чисел, разделенных пробелами. Найти наибольшее из этих чисел. Помогите, люди. Писать надо через ifstream и ofstream (необязательно, чтобы были оба).
Т.к. я не понимаю в программировании, прошу написать мне эту программку. Буду очень благодарен



0



isobo531

50 / 49 / 29

Регистрация: 11.11.2014

Сообщений: 332

17.08.2015, 11:27

2

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
#include <iostream>
#include <conio.h>
#include <fstream>
 
using std::cout;
using std::cin;
using std::endl;
 
int main()
{
    setlocale (LC_ALL, "russian");
 
    std::ifstream f("D:\job.txt");
 
    const int n = 9;
    int *arr = new int [n];
 
    for(int i = 0; i < n; i++)
        f >> arr[i];
 
    int num(0);
    for(int i = 0; i < n; i++)
        if(arr[i] > num)
            num = arr[i];
 
    std::ofstream x ("D:\job1.txt");
 
    x << "Max: " << num << endl;
 
    delete [] arr;
 
    _getch();
    return 0;
}

Добавлено через 1 минуту
В файле я написал 9 чисел.
В файл записывает максимальное число.



0



zss

Модератор

Эксперт С++

13100 / 10373 / 6206

Регистрация: 18.12.2011

Сообщений: 27,739

17.08.2015, 11:32

3

isobo531, в Вашем коде есть недостатки.
1. Количество чисел ограничено 9. их запоминать не надо, поэтому прекращать ввод надо по концу файла.
2. Номер максимального элемента найден с ошибкой

C++
1
2
3
4
 int num(0);
    for(int i = 1; i < n; i++)
        if(arr[i] > arr[num])
            num = i;



0



KrYpToDeN

3 / 3 / 1

Регистрация: 10.01.2015

Сообщений: 69

17.08.2015, 11:33

4

Лучший ответ Сообщение было отмечено EgorVans как решение

Решение

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
// ConsoleApplication14.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <fstream>
#include <iostream>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "RUSSIAN");
 
    ifstream f("Float.txt");
    if (!f.is_open())
    {
        cout << "Файл не открылся:(";
        system("pause");
        return 0;
    }
    float ch = 0.0;
    f >> ch;
 
    while (!f.eof())
    {
        float temp_ch;
        f >> temp_ch;
 
        if (temp_ch > ch)
        {
            ch = temp_ch;
        }
    }
 
    cout << "Максимальное число = " << ch << endl;
 
    system("pause");
    return 0;
}

В папке с файлом должен быть файлик Float.txt c дробными числами через пробел.



1



0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

17.08.2015, 11:35

 [ТС]

5

zss, а вы можете исправить код выше, чтобы был без недостатков? Просто я даже этого не знаю



0



3 / 3 / 1

Регистрация: 10.01.2015

Сообщений: 69

17.08.2015, 11:35

6

как-то сложно..зачем массив?



0



50 / 49 / 29

Регистрация: 11.11.2014

Сообщений: 332

17.08.2015, 11:35

7

Ошибся.. Не так понял..



0



Модератор

Эксперт С++

13100 / 10373 / 6206

Регистрация: 18.12.2011

Сообщений: 27,739

17.08.2015, 11:39

8

KrYpToDeN, Та же ошибка. Не сработает, если все числа отрицательные.



0



0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

17.08.2015, 11:42

 [ТС]

9

KrYpToDeN, ошибка в строке 10

D:QtProjectstxtfilesV1Z2main.cpp:6: предупреждение: unused parameter ‘argc’ [-Wunused-parameter] int _tmain(int argc, _TCHAR* argv[])



0



3 / 3 / 1

Регистрация: 10.01.2015

Сообщений: 69

17.08.2015, 11:48

10

zss, всё сработает)

Не могу картинку вставить(

Из чисел -1.3 -0.23 -1.1 -1.2
Выдает -0.23

Верно же, вроде)

Добавлено через 3 минуты
EgorVans, у тебя, видимо, компилятор другой.
Замени int _tmain(int argc, _TCHAR* argv[]) на int main()



1



0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

17.08.2015, 11:50

 [ТС]

11

KrYpToDeN, наверное ошибка изза Qt…ты же в MVS писал?



0



3 / 3 / 1

Регистрация: 10.01.2015

Сообщений: 69

17.08.2015, 11:51

12

EgorVans, да) в QT я хз, как там..

Перекинь просто всё содержимое из моей функции _tmain в функцию main в QT.

И библиотеки не забудь)



0



0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

17.08.2015, 11:57

 [ТС]

13

KrYpToDeN, всегда пишет что файл не может открыться..я не понимаю почему: и путь к файлу указывал и без пути в папку с заданием клал….все равно он его не видит



0



Модератор

Эксперт С++

13100 / 10373 / 6206

Регистрация: 18.12.2011

Сообщений: 27,739

17.08.2015, 15:02

14

Путь надо указывать в виде
D:\aaaa\bbbbb\file.txt
двойные слаши



0



Mr.X

Эксперт С++

3222 / 1749 / 435

Регистрация: 03.05.2010

Сообщений: 3,867

18.08.2015, 02:49

15

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
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    std::ifstream   ifile("f.txt");
 
    if( !ifile )
    {
        std::cout   <<  "!!!!!!!!!!!!!!!"
                    <<  std::endl;
    }
    else
    {
        std::cout   <<  *std::max_element
                            (
                                std::istream_iterator<double>   ( ifile ),
                                std::istream_iterator<double>   ()
                            )
 
                    <<  std::endl;
    }//else
 
 
    system("pause");
}



1



0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

18.08.2015, 10:37

 [ТС]

16

Mr.X, не робит..всегда знаки восклицательные выдает



0



Эксперт С++

3222 / 1749 / 435

Регистрация: 03.05.2010

Сообщений: 3,867

18.08.2015, 10:49

17

Цитата
Сообщение от EgorVans
Посмотреть сообщение

всегда знаки восклицательные выдает

Сообщает, что не найден входной файл. Создайте и заполните текстовый файл с именем f.



1



0 / 0 / 0

Регистрация: 13.07.2015

Сообщений: 34

18.08.2015, 10:52

 [ТС]

18

KrYpToDeN, спасибо! я все исправил и работает)



0



Задание от репетитора, не знаю как его сделать, вот что имею:

f = open("8.2.txt")
s = f.readline()
maximum = 0

CrazyElf's user avatar

CrazyElf

65.4k5 золотых знаков19 серебряных знаков50 бронзовых знаков

задан 29 мар в 8:36

 KAYRO's user avatar

2

Покажу вам примерный шаблон для вашего решения:

maximum = 0
with open("8.2.txt") as f:
    for line in f:
        # тут нужно сделать из строки line число
        # тут нужно сравнить это число с maximum
        # если число больше maximum, то теперь maximum - это число из файла

# напечатать maximum

ответ дан 29 мар в 8:41

CrazyElf's user avatar

CrazyElfCrazyElf

65.4k5 золотых знаков19 серебряных знаков50 бронзовых знаков

#pascal #freepascal #turbo-pascal

#Паскаль #freepascal #turbo-pascal

Вопрос:

Я должен найти наибольшее число из текстового файла. Числа, например:

 9 8 7 6 5
  

Кто-то сказал мне, что это должно сработать, но это не сработало, и я понятия не имею, как работать с bcs файлов.

 program file;
uses crt;
var i,count,help:integer;

numb:array [1..9] of integer;
f:text;

begin
clrscr;

 assign(f,'file1.txt');
 reset(f);

   readln(f,count);

   for i:=1 to count do

    readln(f,numb[i]);

 close(f);

 for i:=2 to count do
  begin

   if (numb[i-1] < numb[i]) then

     help:=numb[i-1];

     numb[i-1]:=numb[i];

     numb[i]:=help;

  end;  

 for i:=1 to count do
  begin

   write(numb[i]);
  end;

readln;
end.
  

Комментарии:

1. Сначала вам нужно уточнить, как числа расположены в файле. Каждое число находится в отдельной строке, как предполагает ваш код, или все числа разделены пробелом в той же строке, в которой вы их показываете? Указывает ли первое число, сколько в нем чисел, опять же, как предполагает ваш код? Почему вы меняете местами числа во втором for цикле, если вам нужно только найти наибольшее число? Кроме того, помните, что два или более операторов кода, которые должны выполняться вместе, должны находиться в begin end блоке.

Ответ №1:

Если вы хотите узнать только наибольшее число, вы можете использовать текущий максимум при чтении чисел в файле.

Вам, как пользователю, не обязательно знать, сколько чисел содержится в файле. Программа должна определить это.

Я написал небольшой тестовый файл, который называетсяfile1.txt:

 9 8 7 6 3 11 17
32 11 13 19 64 11 19 22
38 6 21 0 37
  

И я только читаю числа, сравнивая их с Max . Это все, что вам нужно.

  • Нет необходимости считывать данные в массив и
  • нет необходимости (пытаться) сортировать данные. Вам нужно только наибольшее число, верно?
  • И пользователю также не нужно знать или вводить количество чисел в текстовом файле.
 program ReadMaxNumber;

uses
  Crt;

var
  Max, Num: Integer;
  F: Text;

begin
  ClrScr;
  Assign(F, 'file1.txt');
  Reset(F);

  Max := -1;
  while not Eof(F) do
  begin
    Read(F, Num);
    if Num > Max then
      Max := Num;
  end;

  Close(F);
  Writeln('Maximum = ', Max);
  Readln;
end.
  

Когда я запускаю это, результат соответствует ожидаемому:

 Maximum = 64
  

Ответ №2:

В предоставленном коде есть несколько ошибок:

  1. Имя программы — file. Название программы не может быть ключевым словом;
  2. Вы считываете из файла переменную count , но фактическое значение не может быть найдено в файле, поэтому count=0 . По этой причине for цикл, который считывает данные из файла, никогда не выполняется. Вы либо читаете его из файла, либо с клавиатуры (в приведенном ниже решении я выбрал второй вариант);
  3. Вы используете readln при чтении из файла. readln перемещает курсор на следующую строку после считывания данных. Это означает, что в numb сохраняется только первое число, 9. Заменить readln на read ;
  4. Во втором for цикле вы говорите это if ... then . Если вы хотите, чтобы все три инструкции были выполнены (а я думаю, что вы хотите, потому что это обмен значениями), поместите их между begin и end . В противном случае выполняется только первая команда, если условие истинно, остальные выполняются всегда;
  5. Метод определения максимального значения является излишним. Лучше, если вы возьмете переменную, max , которая изначально получает значение первого элемента в массиве, затем вы циклически вводите остальные значения, чтобы увидеть, больше ли значение, чем max .

Конечный код выглядит следующим образом:

     program file1;
    uses crt;
    var i,count,help, max:integer;

    numb:array [1..9] of integer;
    f:text;

    begin
     clrscr;
     assign(f,'file1.txt');
     reset(f);  
     writeln('Please input a number for count :');      
     readln(count);  
     for i:=1 to count do  
        read(f,numb[i]);
     close(f);
     max:=numb[1];
     for i:=2 to count do
       if numb[i]>max then
        max:=numb[i];
     write('The result is: ',max); 
    readln;
    end.
  

Комментарии:

1. Я предполагаю, что код для инициализации max должен быть max:=numb[1]

2. Правильно. Я написал эту часть в спешке.

3. Если вы только хотите узнать наибольшее число и ничего больше, вы действительно можете сделать это, не сохраняя их в массиве. Просто сохраняйте максимальное значение при чтении чисел. Теперь, если вам все равно нужны числа для чего-то другого, тогда ваш код в порядке.

4. Также: зачем запрашивать у пользователя количество? Программа должна остановить цикл, если больше нет чисел для чтения. Вам не нужно спрашивать пользователя.

5. Я адаптировал программу в соответствии с тем, что он хочет. Ваши наблюдения верны.

На этой странице вы узнаете

  • Как научить программу читать по-настоящему?
  • Цикл долой: как одной строкой изменить все данные списка?
  • Почему вообще одно число делится на другое?

Трудно найти иголку в стоге сена? Труднее найти две. А еще труднее — найти две конкретные иголки, которые будут дополнять друг друга. Давайте поговорим, как можно решить такую задачу быстро и эффективно при помощи программирования.

Постановка проблемы. Переборное решение

Анализ больших данных — частая проблема, с которой приходится сталкиваться программистам. И дело не в том, что это сложно. Сложно сделать это быстро

В статье «Практика оптимального программирования. Поиск делителей числа» мы уже занимались поиском подходящих чисел на достаточно больших диапазонах. Чтобы программа работала быстрее, мы находили способы сократить перебор и не считать лишние данные. Такой подход работает не всегда.

Например, на таком условии задачи: из указанного массива чисел выбрать два таких, чтобы их произведение было кратным 14 и наибольшим, а также вывести на экран это произведение.

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

Что нам понадобится для реализации такой программы?

  1. Сам массив с числами.
  2. Два цикла for, причем второй будет вложен в первый. Внешний цикл будет перебирать сами числа от первого до предпоследнего, внутренний — все последующие числа (от следующего числа до самого последнего).
  3. Проверка подходящей пары.
  4. Заранее созданная переменная, в которую мы сохраним максимальное подходящее число.

numbers = [21, 16, 4, 45, 35, 9, 88, 76, 77, 18]

max_couple = 0

for first in range(len(numbers) - 1):
	for second in range(first + 1, len(numbers)):
		if ((numbers[first] * numbers[second]) % 14 == 0 and max_couple < numbers[first] * numbers[second]):
			max_couple = numbers[first] * numbers[second]

print(max_couple)

Вывод: 6776

Прекрасно, все работает, и даже достаточно быстро. Но для десяти чисел можно было не писать программу, мы бы и вручную справились. Будет ли работать это решение, если чисел будет 100? 1000? 10000? И как передать такой объем данных в программу?

Чтение данных из файла

Когда данных очень много, неудобно записывать их прямо в программе. Проще хранить их в отдельном файле, и в нем же редактировать. 

Как научить программу читать по-настоящему?

Отдельные текстовые данные можно хранить в отдельном текстовом файле формата .txt. Программа сможет их прочитать и использовать в дальнейшем.

Для открытия файлов в Python используется следующая запись:

<переменная> = open(“<путь к файлу>”, “<режим доступа>”)

Разберем элементы этой записи:

  • Сам файл будет записан в указанную переменную, что позволит нам работать с ним как, собственно, с переменной.
  • Команда open откроет файл по указанному пути.
  • Если текстовый файл лежит в одной папке с файлом вашей программы, то в качестве пути файла можно указать только его имя — программа найдет его в своей же папке.

Если же файл находится в другом месте, необходимо прописывать полный путь

  • Режим доступа — дополнительный параметр. Файл можно открыть так, чтобы его можно было читать, но нельзя в него ничего записывать. Или наоборот — открыть файл на запись, но тогда он будет переписан, а прочитать его мы не сможем.
    • режим “r” откроет файл только на чтение;
    • режим “w” — только на запись, причем этот режим полностью очистит документ;
    • режим “a” позволит дописывать информацию к имеющейся. 

Если не указать этот параметр совсем, файл будет открыт по умолчанию только на чтение.

Чтобы считывать данные из файла, есть несколько способов:

  • команда readline будет считывать по одной строке текстового файла;
  • readlines создаст массив, в котором будут храниться сразу все строки файла;
  • как строку или массив, файл можно перебирать с помощью цикла for.

Важно запомнить — читаются данные из файла именно в строковом формате. Если нужно преобразовать их к числам, делаем это с помощью команды int.

Если у нас есть текстовый документ text.txt, в котором прописаны необходимые числа — каждое в новой строке — у нас есть несколько способов создать массив, содержащий все эти числа. Для удобства, пусть в первой строке файла будет количество чисел для обработки.

Цикл долой: как одной строкой изменить все данные списка?

В последнем примере мы использовали функцию map. Она занимается тем, что применяет определенную команду ко всем элементам переданного ей массива. В данном случае мы создали массив со всеми числами файла командой file.readlines(). Так как из файла считывается строковой тип данных, функцией map мы применили команду int сразу ко всем считанным числам. Но сам map список не создаст, потому мы ему поможем командой list.

В итоге результат один — в списке numbers будут находиться все числа из файла в количестве count штук.

Допишем эту часть в наш код и попробуем запустить:


file = open("text.txt")
count = int(file.readline())
numbers = list(map(int, file.readlines()))


max_couple = 0

for first in range(len(numbers) - 1):
	for second in range(first + 1, len(numbers)):
		if ((numbers[first] * numbers[second]) % 14 == 0 and max_couple < numbers[first] * numbers[second]):
			max_couple = numbers[first] * numbers[second]

print(max_couple)

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

  • 100 чисел — 0.1 секунда;
  • 1000 чисел — 0.2 секунды;
  • 10000 чисел — 6.5 секунды.

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


file = open("text.txt")
count = int(file.readline())
numbers = list(map(int, file.readlines()))

max_couple = 0

for first in range(len(numbers) - 2):
	for second in range(first + 1, len(numbers) - 1):
		for third in range(second + 1, len(numbers)):
			if ((numbers[first] * numbers[second] * numbers[third]) % 14 == 0 and max_couple < numbers[first] * numbers[second] * numbers[third]):
				max_couple = numbers[first] * numbers[second] * numbers[third]

print(max_couple)

И снова засекаем время:

  • 100 чисел — 0.2 секунды;
  • 1000 чисел — 45.5 секунды;
  • 10000 чисел — за 8 часов программа так и не выполнилась.

Это явно не самый успешный результат. От перебора надо избавляться и придумывать что-то хитрее. 

Произведение множителей

Почему вообще одно число делится на другое?
Все числа можно разложить на произведение простых множителей. Например:
4 = 2 * 2
12 = 2 * 2 * 3
22 = 2 * 11

И если все множители одного числа есть во втором, то второе число можно разделить на первое. Например, среди множителей 12 есть две двойки, а у 4 все множители — двойки. Значит, 12 можно разделить на 4.

По условию задачи нам нужно произведение, которое кратно 14. Число 14 можно разложить как 2 * 7. Значит, в искомом произведении среди множителей должны найтись 2 и 7. Например:

  • Если умножить 4 на 21, в разложении получится 4 * 21 = 2 * 2 * 3 * 7. Среди множителей есть 2 и 7, тогда это произведение поделится на 14.
  • Если умножить 14 на 17, мы получим 14 * 17 = 2 * 7 * 17. Так как в произведении уже есть 14, оно уже будет кратно 14, какое бы второе число мы ни подставили.
  • Если умножить 15 на 18, получим 15 * 18 = 3 * 5 * 2 * 3 * 3. Семерки среди множителей нет, значит, это произведение не будет кратно ни 7, ни 14.

Значит, чтобы получить произведение, кратное 14, надо чтобы один из множителей был кратен 14, либо одно из чисел кратно 2, а второе — 7. Отсортируем заранее все числа из файла по группам: кратные 14, кратные 7, кратные 2 и не кратные ничему из этого. Тогда найти необходимое произведение не составит труда.

Оптимальная программа будет состоять из следующих элементов:

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

Как мы уже выяснили раньше, подходящей парой будет та, в которой одно число будет кратно 14, а второе — вообще любое, в том числе другое кратное 14. Либо нужна пара, в которой одно число кратно 2, а второе — 7. Так как нам нужно наибольшее произведение, будем брать наибольшие множители. Нам поможет команда max и сортировка по убыванию — наибольшие элементы будут в самом начале массива, их будет удобно брать по индексам.

Далее в этой статье будем работать вот с этим файлом: text.txt.


file = open("text.txt")
count = int(file.readline())

kr14 = []
kr7 = []
kr2 = []
nekr = []

for number in file:
	if int(number) % 14 == 0:
		kr14.append(int(number))
	elif int(number) % 7 == 0:
		kr7.append(int(number))
	elif int(number) % 2 == 0:
		kr2.append(int(number))
	else:
		nekr.append(int(number))

kr14.sort(reverse = True)
kr7.sort(reverse = True)
kr2.sort(reverse = True)
nekr.sort(reverse = True)

ans1 = kr14[0] * max(kr14[1], kr2[0], kr7[0], nekr[0])
ans2 = kr2[0] * kr7[0]

print(max(ans1, ans2))

Вывод: 99890000

Выполнение программы на огромном диапазоне чисел не заняло много времени.

Умея читать большое количество данных из файла, а также умея грамотно распределять числа, давайте решим еще одну проблему — поиск не произведения, а суммы.

Остатки от деления

Теперь мы хотим найти пару чисел, сумма которой будет кратна 17. Как проверить кратность суммы?

Обратимся к математике

Кратное 17 число можно представить как 17n, где n — натуральное число (1, 2, 3 и так далее). 

Если число не кратно 17, то его можно представить как 17n + m, где m будет остатком от деления числа на 17.

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

  • если сложить два числа, кратных 17, никаких проблем не будет — 17n1 + 17n2 = 17(n1 + n2), среди множителей сразу появляется 17, значит, сумма будет кратна 17;
  • если числа будут с какими-то остатками от деления, то понадобится дополнительное условие: 17n1 + m1 + 17n2 + m2 = 17 * (n1 + n2) + m1 + m2. Надо вынести 17 в общий множитель, чтобы все выражение было кратно 17.

m1 и m2 не могут быть кратны 17 по отдельности, так как это остатки от деления. Значит, их сумма должна быть кратна 17, то есть m1 + m2 = 17n3. Только тогда мы сможем вынести 17 общим множителем.

Нам снова придется сортировать числа, но не по кратности, а по остаткам от деления. Остатком от деления на 17 может быть любое число от 0 до 16. Здесь мы можем создать двумерный список, про который мы говорили в статье «Работа с массивами в Python». Нам нужно 17 внутренних списков, которые будут иметь индексы от 0 до 16. В каждый мы сможем заносить числа по остаткам от деления — чтобы остаток был равен индексу.

В коде нам понадобятся:

  • Заранее созданный двумерный список с 17 пустыми списками внутри.
  • Сортировка чисел файла по внутренним спискам. Какой остаток от деления на 17, такой и индекс внутреннего списка;
  • Сортировка внутренних списков для удобства.
  • Список, в который мы будем складывать потенциальные ответы.
  • Потенциальные ответы — сумма наибольших чисел внутренних массивов с индексами i и 17 — i .В сумме они должны дать  ровно 17 — это и обеспечит нам необходимую сумму. Перебирать i будет достаточно до 8. При i = 8 мы проверим индексы 8 и 9, а при i = 9 — 9 и 8, то есть начнем повторяться.
  • Для i = 0, чисел, кратных 17, проверка должна быть отдельной, так как мы будем брать два таких наибольших числа.
  • Перед подсчетом любой суммы — поверка:  
    • есть числа с необходимыми остатками от деления — считаем;
    • нет таких чисел — считать нечего.
  • Ответ — наибольший из потенциальных.

Следующий код полностью выполнит все необходимые требования, и работать будет очень быстро:


file = open("text.txt")
count = int(file.readline())

kr = []
for i in range(17):
	kr.append([])

for number in file:
	number = int(number)
	kr[number % 17].append(number)

for i in range(17):
	kr[i].sort(reverse = True)

ans = []

if len(kr[0]) >= 2:
	ans.append(kr[0][0] + kr[0][1])

for i in range(1, 9):
	if len(kr[i]) > 0 and len(kr[17 - i]) > 0:
		n = kr[i][0] + kr[17 - i][0]
		ans.append(n)

print(max(ans))

Вывод: 19992

Фактчек

  • Для открытия файла в программе используется команда open, а для чтения данных из него — команды readline (читает одну строку) и readlines (считает сразу все).
  • Произведение чисел будет кратно n, если среди множителей этого произведения можно найти такие, произведение которых будет равно n.
  • Сумма чисел будет кратна n, если сумма их остатков от деления будет кратна n.

Проверь себя

Задание 1.
В каких ситуациях переборное решение не будет работать?

  1. Во всех. Это решение бесполезно и не имеет права на существование.
  2. В определенных, это всегда зависит от условия задачи.
  3. При очень большом количестве перебираемых данных.
  4. Ни в каких. Это хорошее решение, которое можно использовать в любой ситуации.

Задание 2.
В файле  text.txt найдите наибольшее произведение двух чисел, которое будет кратно 21.

  1. 99880011
  2. 99878121
  3. 99922211
  4. Такого произведения нет

Задание 3.
В файле text.txt найдите наибольшую сумму двух чисел, которая будет кратна 11.

  1. 11110
  2. 19987
  3. 19998
  4. Такой суммы нет

Ответы: 1. — 3; 2. — 1; 3. — 3.

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как найти интересного писателя
  • Составить рассказ как я провел воскресенье
  • Как исправить ошибку 0 xc 0000142
  • Порвался наушник как исправить
  • Как составить брачный договор на ипотечную квартиру купленную в браке при разводе

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии