B1a=<(17,Y),(23,H),(60,I)>,B2a=<(90,S),(66,T),(77,T)>,B3a=<(50,U),(88,W),(30,S)>.
Додаючи усюди ще і початкову позицію елемента в списку, одержуємо:
B1a'=<(1,17,Y),(2,23,H),(3,60,I)>,B2a'=<(4,90,S),(5,66,T),(6,77,T)>,B3а'=<(7,50,U),(8,88,W),(9,30,S)>.Якщо як індексну функцію вибрати іншу функцію Gb(K)=1+(поз.K-1)%3, то одержимо списки:
B1b"=<(1,17,Y),(4,90,S),(7,50,U)>,B2b"=<(2,23,H),(5,66,T),(8,88,U)>,B3b"=<(3,60,I),(6,77,T),(9,30,S)>.Тепер для перебування вузла K6 досить переглянути тільки одну з трьох послідовностей (списків). При використанні функції Ga(K) це список B2а', а при функції Gb(K) список B3b".
Для індексної функції Gc(K)=1+K1/100, де K1 - перший компонент елемента ДО, знаходимо:
B1=<(17,Y),(23,H),(60,I),(90,S)>,B2=<(66,T),(77,T)>,B3=<(50,U),(88,W)>,B4=<(30,S)>.Щоб знайти тут вузол К с першим компонентом-ключем ДО1=77, досить переглянути список B2.
При реалізації індексного збереження застосовується методика А для збереження індексного списку Х (функція Ga(X) ) і методика C для збереження підсписків B1,B2,...,Bm (функція Gc(Bi)), тобто використовується, так називане, A-C індексне збереження.
У практиці часто використовується послідовно-зв'язане індексне збереження. Тому що звичайно довжина списку індексів відома, те його зручно зберігати послідовно, забезпечуючи прямій доступ до будь-якого елемента списку індексів. Підсписки B1,B2,...,Bm зберігаються пов'язано, що спрощує вставку і видалення вузлів(елементів). Зокрема, подібний метод збереження використовується в ЄС ЕОМ для організації, так званих, індексно-послідовних наборів даних, у яких доступ до окремих записів можливий як послідовно, так і за допомогою ключа.
Послідовно-зв‘язане індексне збереження для приведеного приклада зображене на мал.24, де X=.
Рис.12.
Розглянемо ще одну задачу. На вході задана послідовність цілих позитивних чисел, що закінчується нулем. Скласти процедуру для введення цієї послідовності й організації її індексного збереження таким чином, щоб числа, що збігаються в двох останніх цифрах, містилися в один підсписок.
Виберемо як індексну функцію G(K)=K%100+1, а як індексний список Х - масив з 100 елементів. Наступна функція вирішує поставлену задачу:
#include #include typedef struct nd { float val; struct nd *n; } ND; int index (ND *x[100]) { ND *p; int i,j=0; float inp; for (i=0; i<100; i++) x[i]="NULL;" scanf("%d",&inp); while (inp!="0)" { j++; p="malloc(sizeof(ND));" i="inp%100+1;" p->val=inp; p->n=x[i]; x[i]=p; scanf("%d",&inp); } return j; }Значенням функції, що повертається, index буде число оброблених елементів списку.
Для індексного списку також може використовуватися індексне збереження. Нехай, наприклад, мається список B= з елементами
K1=(338,Z), K2=(145,A), K3=(136,H), K4=(214,I), K5 =(146,C),K6=(334,Y), K7=(333,P), K8=(127,G), K9=(310,O), K10=(322,X).Потрібно розділити його на сімох підсписків, тобто X= таким чином, щоб у кожен список B1,B2,...,B7 попадали елементи, що збігаються в першому компоненті першими двома цифрами. Список Х, у свою чергу, будемо індексувати списком індексів Y=, щоб у кожен список Y1,Y2,Y3 попадали елементи з X, у яких у першому компоненті збігаються перші цифри. Якщо списки B1,B2,...,B7 зберігати пов'язано, а списки індексів X,Y індексно, те такий спосіб збереження списку B називається зв'язаним індексним збереженням. Графічне зображення цього збереження приведене на мал.25.
Рис.13. зв'язане індексне збереження списку.
Практична частина
Результатом нашої роботи є програмний комплекс для роботи (розробки) візитних карток (мал. 1). Для економії часу при розробці програми ми використали деякі вже готові функції для роботи з графікою.
Мал. 1. Лістинг модуля функцій для роботи з графікою.
Основною частиною програми є модуль для роботи з графічним форматом BMP (лістинг 1).
Лістинг 1.
/* windows bmp format image storage */
BMPsave(int x,int y,int x1,int y1,char a[])
{
struct bmp
{unsigned char name[3];
unsigned char dummy[15];
unsigned int x;
unsigned char dummy1[2];
unsigned int y;
unsigned char dummy2[1];
}bmphead;
FILE *fp,*fq;
int xlen,ylen,i,j,count;
unsigned char c,ch;
fp=fopen(a,"wb");
fq=fopen("electron.bmp","rb");
/*fq=fopen("electron.bmp","rb");*/
if (fp==NULL) return(-1);
fread(&bmphead,sizeof(struct bmp),1,fq);
xlen=x1-x+1;
ylen=y1-y+1;
bmphead.x=xlen;
bmphead.y=ylen;
fwrite(&bmphead,sizeof(struct bmp),1,fp);
for(i=0;i<=1052;i++)
{
fread(&ch,1,1,fq);
fwrite(&ch,1,1,fp);
}
fclose(fq);
/*hidemouse();*/
count=0;
for(j=y1;j>=y;j--)
{
/*setcolor(BLUE);
line(201+count,426,201+count,444);*/
count++;
for(i=x;i<=x1;i++)
{c=getpixel(i,j);
switch(c)
{
case 0: c=0;break;
case 1: c=12;break;
case 2: c=4;break;
case 3: c=5;break;
case 4: c=16;break;
case 5: c=7;break;
case 6: c=13;break;
case 7: c=15;break;
case 8:c = 1;break;
case 9:c=10;break;
case 10: c=18;break;
case 11: c=24;break;
case 12: c=2;break;
case 13: c=21;break;
case 14: c=22;break;
case 15: c=14;break;
}
fwrite(&c,1,1,fp);
}
fwrite(&c,1,1,fp);
c=0;
fwrite(&c,1,1,fp);
}
count--;
/*setcolor(LIGHTGRAY);
for(i=426;i<=444;i++)
line(201,i,201+count,i);*/
/*showmouse();*/
fclose(fp);
return(0);
}
/* windows bmp format image retrieval */
BMPload(int x,int y,char a[])
{
struct bmp
{unsigned char name[3];
unsigned char dummy[15];
unsigned int x;
unsigned char dummy1[2];
unsigned int y;
unsigned char dummy2[1];
}bmphead;
FILE *fp,*fq;
int xlen,ylen,i,j,diff,count;
unsigned char c,ch;
fp=fopen(a,"rb");
if (fp==NULL) return(-1);
fread(&bmphead,sizeof(struct bmp),1,fp);
if (!(bmphead.name[0]=='B' && bmphead.name[1]=='M'))
{fclose(fp);
return(-2);
}
if (bmphead.name[2]!=250 && bmphead.name[2]!=70)
{fclose(fp);
return(-3);
}
if (bmphead.x>600 || bmphead.y>400)
{fclose(fp);
return(-4);
}
for(i=0;i<=1052;i++)
{
fread(&ch,1,1,fp);
}
/*hidemouse();*/
if (bmphead.name[2]==250) diff=1;
else
if (bmphead.name[2]==70) diff=0;
count=0;
/*hidemouse();*/
/*setcolor(WHITE);
for(i=82;i<=getmaxx()-12;i++)
line(i,47,i,getmaxy()-72); */
for(j=y+bmphead.y-2;j>=y;j--)
{
/*setcolor(BLUE);
line(201+count,426,201+count,444);*/
count++;
for(i=x;i<x+bmphead.x+diff;i++)
{
fread(&c,1,1,fp);
switch(c)
{
case 0: c=0;break;
case 12: c=1;break;
case 4: c=2;break;
case 5: c=3;break;
case 16: c=4;break;
case 7: c=5;break;
case 13: c=6;break;
case 15: c=7;break;
case 1:c = 8;break;
case 10:c=9;break;
case 18: c=10;break;
case 24: c=11;break;
case 2: c=12;break;
case 21: c=13;break;
case 22: c=14;break;
case 14: c=15;break;
}
putpixel(i-100,j-50,c);
}
if (bmphead.name[2]==250)
fread(&c,1,1,fp);
}
count--;
/*setcolor(LIGHTGRAY);
for(i=426;i<=444;i++)
line(201,i,201+count,i);*/
/* showmouse();*/
fclose(fp);
return(0);
}
Інтерфейс програми базується на роботі з мишкою та програмним інтерфейсом користувача (Лістинг 2).
Лістинг 2.
class mouse
{
private:
union REGS i,o;
struct SREGS s;
public:
mouse()
{
initmouse();
showmouseptr();
}
void initmouse()
{
i.x.ax=0;
int86(0x33,&i,&o);
}
void showmouseptr()
{
i.x.ax=1;
int86(0x33,&i,&o);
}
void hidemouseptr()
{
i.x.ax=2;
int86(0x33,&i,&o);
}
void getmousepos(int& button,int& x,int& y)
{
i.x.ax=3;
int86(0x33,&i,&o);
button= o.x.bx;
x=o.x.cx;
y=o.x.dx;
}
void restrictmouseptr(int x1,int y1,int x2,int y2)
{
i.x.ax=7;
i.x.cx=x1;
i.x.dx=x2;
int86(0x33,&i,&o);
i.x.ax=8;
i.x.cx=y1;
i.x.dx=y2;
int86(0x33,&i,&o);
}
void changemouseptr(int mark[50],int xstart,int ystart)
{
i.x.ax=9;
i.x.bx=xstart;
i.x.cx=ystart;
i.x.dx=(int)mark;
segread(&s);
s.es=s.ds;
int86x(0x33,&i,&i,&s);
}
};
Головний модуль програми відповідає за управління всіма цими компонентами (лістинг 3).
Лістинг 3.
/* FILE NO: A
auxillary file for img3.cpp ie- Imager 3.1
*/
void toolset(int);
void lift(int);
int imagearea();
void fillwindow();
void back(int,int,int,int,int);
void backtotal(int,int,int,int,int);
void myrect(int,int,int,int);
void ba(int,int,int,int,int);
void invertcolors();
void fliphorizontal();
void flipvertical();
void aboutwindow();
void textgetter(char *);
void saveimage(int,int,int,int,char *);
void loadimage(int,int,char *);
void cut();
void copy();
void paste();
void changer(int);
void say(char *);
void filemenu();
void editmenu();
void start()
{ m.hidemouseptr();
openwindow(0,0,639,479,title,1,1,1,3,9);
buttonon(5,20,35,35,"File",4);
buttonon(40,20,70,35,"Edit",4);
buttonon(75,20,105,35,"View",4);
buttonon(110,20,145,35,"About",3);
setfillstyle(1,15);
// defining buttons *!*
ba(0,0,0,0,0);
ba(5,20,35,35,1);
ba(40,20,70,35,2);
ba(75,20,105,35,3);
ba(110,20,145,35,4);
bar(100,50,635,450);
char *labels[]={"Paint","Draw","Line","ellipse","Box","Text","Spray","Inv.Col","Cut","Copy","Paste","Select","Erase","H.flip","V.flip","Font","Filler","S.Save","Change","BMP","",""};
int cnta=0;
int tools=5;
for(int cnt=50;cnt<=300;cnt+=20)
{ buttonon(5,cnt,45,cnt+15,labels[cnta],3);
ba(5,cnt,45,cnt+15,tools);
tools++;
buttonon(50,cnt,95,cnt+15,labels[cnta+1],3);
ba(50,cnt,95,cnt+15,tools);tools++;
if(cnta<20)
{cnta+=2;}
}
setfillstyle(1,4);
bar(5,320,85,370);
buttonclick(5,320,85,370);
settextstyle(4,0,2);outtextxy(11,330,"Imager");settextstyle(2,0,4);
int cl=0;
for(int cntb=400;cntb<=410;cntb+=10)
{ for(int cntc=5;cntc<=80;cntc+=10)
{ setfillstyle(1,cl);
bar(cntc,cntb,cntc+10,cntb+10);
if(cl<=15)
{ cl++;}
}
}
setfillstyle(1,0);
bar(5,430,85,450);
/*buttonon(25,455,70,470,"Modify",5);*/
ba(639-13,3,639-3,12,31);
ba(5,400,85,420,32);
ba(100,50,635,450,33);
ofstream o("ccp.dat");
o<<0<<endl<<0;
o.close();
m.showmouseptr();
/*music("imager3.snd");*/
}
void ba(int x1,int y1,int x2,int y2,int n)
{ buttons[n][0]=x1;
buttons[n][1]=y1;
buttons[n][2]=x2;
buttons[n][3]=y2;
}
int imagearea()
{ m.getmousepos(button,x,y);
if((x>100)&&(y>50)&&(x<635)&&(y<450))
{return(1);}
else {return(0);}
}
void myrect(int x1,int y1,int x2,int y2)
{ line(x1,y1,x2,y1);
line(x1,y1,x1,y2);
line(x1,y2,x2,y2);
line(x2,y1,x2,y2);
}
void back(int x1,int y1,int x2,int y2,int mode)
{ int ch;char c2;
if(mode==0)
{
ofstream outfile("im~temp.dat");
for(int a=x1;a<=x2;a++)
{ for(int b=y1;b<=y2;b++)
{ ch=getpixel(a,b);
outfile<<(char)(ch+28);
}
}
outfile.close();
}
else if(mode==1)
{
ifstream infile("im~temp.dat");
for(int a=x1;a<=x2;a++)
{ for(int b=y1;b<=y2;b++)
{ infile.get(c2);ch=(int)c2;
putpixel(a,b,ch-28);
}
}
infile.close();
}
}
void fillwindow()
{ m.hidemouseptr();
back(200,150,350,200,0);
openwindow(200,150,350,200,"Filler",1,6,2,7,10);
buttonon(210,183,240,198,"ON",4);
ba(210,183,240,198,34);
buttonon(300,183,330,198,"OFF",4);
ba(300,183,330,198,35);
m.showmouseptr();
loop(34,35);
m.hidemouseptr();
back(200,150,350,200,1);
loopmain=1;
m.showmouseptr();
}
void fontwindow()
{ m.hidemouseptr();
back(200,100,405,350,0);
openwindow(200,100,405,350,"Choose Fonts",1,4,0,7,12);
settextstyle(2,HORIZ_DIR,4);
for(int a=0;a<=11;a+=2)
{ if((a==9)||(a==10)) {settextstyle(3,HORIZ_DIR,1);}
else{settextstyle(a,HORIZ_DIR,1);}
buttonon(205,120+((a/2)*30),300,120+25+((a/2)*30),"Imager",2);
ba(205,120+((a/2)*30),300,120+25+((a/2)*30),37+a);
if((a+1==9)||(a+1==10)) {settextstyle(3,HORIZ_DIR,1);}
else{settextstyle(a+1,HORIZ_DIR,1);}