Доброго дня! У мене в лабораторній роботі №2 була задача, яку пропунувалось вирішити за допомогою однієї з мов програмування. Я тоді намагався її написати в матлабі, сидів тоді довгенько, але мені так і не вдалося її реалізувати. Умову тієї задачі і проблеми які в мене виникли при її реалізації можна подивитись
тут, в мому повідомленні за 15 лютого 2012, 02:43.
Багато води витекло з того часу, а я так і не забув, що мав незавершену справу (мабуть я стану привидом

).
Сьогодні мав вільний день+бажання доробити ту задачу. Алгоритм розвязку доступно описаний в наступному за моїм
повідомленням за 15 лютого 2012, 02:43. Тому, тут я наведу тільки код програми, прикріплю саму програму, і опишу деякі незначні проблеми які в мене виникли при реалізації здається такого простого алгоритму.
Цього разу я писав програму на С++ в середовищі MS Visual C++ 2005 Exppress Edition (абсолютно безкоштовний софт, який можна скачати на сайті Майкрософту).
От власне і сам код:
Код:
#include <iostream>
#include <fstream>
#include <map>
using namespace std;
int main(void)
{
map<int,float> load,tmp;
map<int,float>::iterator it;
fstream file("input.txt");
bool watcher=true;
int n=0,tst,too,tmpi=0;
float tmpf=0,tmpf1,ans=0;
char tmpch;
printf("Please enter value of total simulation time(Tm):\n");
cin>>tst;//total simulation time
printf("Please enter value of time of observation(t):\n");
cin>>too;//time of observation
if (!file.good()){
printf("You have some problem with input file(input.txt).\nPerhaps, this file is not exist.\n");
cin.sync();
cin.get();
return 0;
}
do
{
file.get(tmpch);
if (tmpch=='\n'){
watcher=true;
load[n]=tmpf;
n++;
tmpf=0;
tmpi=0;
}
if (tmpch==',') watcher=false;
if (watcher&&(tmpch!='\n')&&(tmpch!=',')) tmpf=tmpf*10+(tmpch-48);
if (!watcher&&(tmpch!='\n')&&(tmpch!=',')){
tmpf1=tmpch-48;
tmpi++;
for (int k=1;k<=tmpi;k++){
tmpf1/=10.0;
}
tmpf+=tmpf1;
}
}
while (!file.eof());
n-=1;
load.erase(load.find(n));
if(n>((((tst*3600)/too))+2)||((tst*3600)/too)>n){
printf("You have some problem with input data.\nPerhaps, input data is not from program Ok_lab1.\n");
printf("Correct input data and try again.\n");
cin.sync();
cin.get();
return 0;
}
tmpi=3600/too;
for(int i=0,k=0; i<tmpi;i++){
tmp[k]+=load[i];
}
for(int i=1;i<n;i++){
tmp[i]=tmp[i-1]-load[i-1]+load[tmpi+i-1];
tmpf1=i;
}
for(int i=0; i<n; i++){
if (tmp[i]==ans) watcher=true;
if (tmp[i]>ans){
ans=tmp[i];
tmpi=i;
watcher=false;
}
}
if(watcher){
printf("There are more then one hour of the largest load:\n");
it=tmp.find(tmpi);
for(int i=0; i<n; i++){
if(it->second==tmp[i]){
printf("%d:%d:%d-%d:%d:%d;\n",i*too/3600,((i*too)%3600)/60,(i*too)%60,i*too/3600+1,((i*too)%3600)/60,(i*too)%60);
}
}
}
else{
int i=tmpi;
printf("There is one hour of the largest load:\n");
printf("%d:%d:%d-%d:%d:%d;\n",i*too/3600,((i*too)%3600)/60,(i*too)%60,i*too/3600+1,((i*too)%3600)/60,(i*too)%60);
}
printf("Thank you!\nPress any key to exit.\n");
cin.sync();
cin.get();
return 0;
}
Як користуватись прогамою:В цій програмі масив послідовностей інтенсивності навантаження на проміжках t слід вводити окремим текстовим файлом з назвою "input.txt" без лапок, тобто створюєте текстовий документ з назвою "input.txt" без лапок, копіюєтете туди масив з пункту чотири програми Ok_lab1 "Дослідження телефонного навантаження", зберігаєте і закриваєте цей текстовий файл. Значення сумарного часу моделювання Tm(год) та значення часу інтервалу спостереження t(c) слід вводити з клавіатури після запуску програми. Файл "input.txt" повинен знаходитись в тій же теці, що і сама програма.
Проблемка яка виникла при реалізації програми і її вирішення:Проблема ця полгає в тому, що масив який ви копіюєєте з програми Ok_lab1 скалдається з десяткових чисел формату "a,b", а не "a.b", тому одразу їх зчитувати як змінні з плаваючою комою не можна, оскільки "a,b" сприймається С++ як символьне значення, а не як числове значення формату "a.b". Звичайно, в текстовому документі всі коми можна замінити на крапки, і не морочити собі голову, але мені здалось, що таке вирішення даної проблеми є дещо не актуальним.
Тому я запропунував вирішення даної проблеми іншим чином:
1) Зчитуємо символ цифри, перетворюємо його в цифру за допомогою ASCII зміщення. Тобто, наприклад символ "1" представляється ASCII як десяткове число 49 (шістнадцяткове 31, двійкове 110001), а число 1 представляється як десяткове 1 (шістнадцяткове 1, двійкове 1). Тобто для того щоб претворити символ "1" в десяткове число 1, від символьного представлення слід відняти десяткове число 48, і в результаті ми отримаємо десяткове число 1. Таким чином можна перетворити символ будь-якої десяткової цифри в десяткову цифру.
2) Зчитуємо наступний символ, і якщо це не "," то ми перетворюємо його в десяткову цифру. Далі число яке ми отримали в попередньому пункті домножуємо на 10, та додаємо до отриманого результату(операцією алгебраїчного додавання) цю отриману цифру. Отримане значення зберігаємо. Зчитуємо настпуний символ, і якщо це не "," то ми перетворюємо його в десяткову цифру, збережений попередньо результат домножуємо на 10 і додаємо до нього цю цифру, зберігаємо отриманий резльтат, і так доти доки не отримаємо символ "," або символ кінця рядка "\n".
3) Якщо ми зчитали символ кінця рядка, то збережене значення і є потрбним нам числом. Якщо ми зчитали символ ",", то нам слід зчитати наступний символ, перетворити його в десяткову цифру, отриману десяткову цифру поділити на 10, та отриманий реузультат додати до попредньо збереженого результату і зберегти тепер уже отриманий результат. Далі зчитуємо наступний символ, і якщо це не символ кінця рядка "\n" то перетворюємо його на цифру, ділимо її тепер уже на 100, додаємо отриманий результат до попередньо збереженого, і збергіаємо новий отриманий результат. Коли отримуємо третій символ після коми то його слід ділити уже на 1000, коли четвертий то слід ділити уже на 10000 і так далі, доти доки не зчитаємо символ кінця рядка "\n". І коли ми врешті зчитали символ кінця рядка, то збережене значення і є потрбним нам числом.
Хух, нарешті описав даний алгоритм. Не знаю наскільки він получився зрозумілий, але я старався.
Тепер лишилось тільки прикріпити саму програму. Зараз прикріплю).
Приєднання файлів:
Hour Of The Largest Load.rar [69.33 Кб]
Завантажено 444 разів
Доречі, в цій програмі передбачений вивід всіх годин найбільшого навантаження, якщо є декілька годин з однаковим найбільшим навантаженням.
P.S. Програма буде працювати на Windows XP, на Windows 7 не гарантою, тому, що там символ кінця рядка може бути відмінним від "\n". А на операційних системах сімейства linux вона працювати не буде, хоча спробуйте, раптом вам пощаситить.

P.P.S. Якщо у когось є подібні задачі, що стосуються телекомунікацій пропонуйте їх мені тут, або в мій Skype: angelokk11.