读进合法的BASIC程序并给语句重新编号,使得第一条语句从F处开始,并且每一个语句的序号比前面一语句高D。

数据结构与算法分析——c语言描述 练习5.12 答案

语句序号可以大到32比特的整树。程序必须以线性时间运行。


basic程序是这样的(出自维基):

10 INPUT "What is your name: "; U$
20 PRINT "Hello "; U$
30 INPUT "How many stars do you want: "; N
40 S$ = ""
50 FOR I = 1 TO N
60 S$ = S$ + "*"
70 NEXT I
80 PRINT S$
90 INPUT "Do you want more stars? "; A$
100 IF LEN(A$) = 0 THEN GOTO 90
110 A$ = LEFT$(A$, 1)
120 IF A$ = "Y" OR A$ = "y" THEN GOTO 30
130 PRINT "Goodbye "; U$
140 END


大概就是用一个hash映射吧。把原来的语句顺序在O(1)复杂度内找到新的语句顺序。

输入上面的程序,然后在新的一行里按Ctrl+z结束输入。


hashQuad.h

typedef int XType;
typedef int YType;

#ifndef _HashQuad_H
#define _HashQuad_H

typedef unsigned int Index;
typedef Index Position;

struct HashTbl;
typedef struct HashTbl* HashTable;

HashTable initializeTable(int tableSize);
void destroyTable(HashTable h);
Position find(XType x, HashTable h);
HashTable insert(XType x,YType y, HashTable h);
HashTable rehash(HashTable h);
YType map(XType x , HashTable h);
int isLegitimate(Position pos, HashTable h);
#endif


hashQuad.cpp

#include"hashQuad.h"
#include"fatal.h"
#include<math.h>
#include<string.h>
#define MinTableSize 5

enum KindOfEntry { Legitimate, Empty, Deleted };

struct ElementType {
	XType x;
	YType y;
};

struct HashEntry {
	ElementType element;
	enum KindOfEntry info;
};

typedef struct HashEntry Cell;

struct HashTbl {
	int tableSize;
	int hasInsertedNum;
	Cell *theCells;//数组
};

static int hash(XType x, int tableSize) {
	return x % (tableSize);
}

static Position hash2(XType x, int tableSize) {
	return 7 - (x % 7);
}


static int isPrime(int num) {
	for (int i = 2; i <= sqrt(num); i++)
		if (num%i == 0)
			return 0;
	return 1;
}
static int nextPrime(int num) {
	int i = num;
	while (!isPrime(i))
		i++;
	return i;
}

int isLegitimate(Position pos, HashTable h) {
	return h->theCells[pos].info == Legitimate;
}


HashTable initializeTable(int tableSize) {
	HashTable h;
	int i;
	if (tableSize < MinTableSize) {
		Error("Table size too small");
		return NULL;
	}
	h = (HashTable)malloc(sizeof(struct HashTbl));
	if (h == NULL)
		FatalError("Out of space!!!");
	h->tableSize = nextPrime(tableSize);
	h->theCells = (Cell*)malloc(sizeof(Cell)*h->tableSize);
	h->hasInsertedNum = 0;
	if (h->theCells == NULL)
		FatalError("Out of space!!!");
	for (i = 0; i < h->tableSize; i++) {
		h->theCells[i].info = Empty;
	}
	return h;
}

void destroyTable(HashTable h) {
	free(h->theCells);
	free(h);
}



static Position find(XType x, HashTable h) {
	Position currentPos = hash(x, h->tableSize);
	int i = 0;
	while (h->theCells[currentPos].info != Empty && h->theCells[currentPos].element.x != x) {
		currentPos += (++i * hash2(x, h->tableSize));
		currentPos = currentPos % h->tableSize;
	}
	return currentPos;
}

HashTable insert(XType x, YType y, HashTable h) {
	if ((double)h->hasInsertedNum / h->tableSize > 0.5)
		h = rehash(h);
	Position pos = find(x, h);
	if (h->theCells[pos].info != Legitimate) {
		h->theCells[pos].element.x = x;
		h->theCells[pos].element.y = y;
		h->theCells[pos].info = Legitimate;
		h->hasInsertedNum++;
	}
	return h;
}

HashTable rehash(HashTable h) {
	HashTable newH = initializeTable(h->tableSize * 2);
	for (int i = 0; i < h->tableSize; i++)
		if (h->theCells[i].info == Legitimate)
			insert(h->theCells[i].element.x, h->theCells[i].element.y, newH);
	destroyTable(h);
	return newH;
}



YType map(XType x, HashTable h) {
	Position p = find(x, h);
	return h->theCells[p].element.y;
}


main.cpp

#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include"hashQuad.h"


int main() {
	HashTable h = initializeTable(200);
	int newNumCnt = 0xf;//从f处开始
	std::vector<std::string> proc;
	std::string line;
	while (std::getline(std::cin, line)) {
		std::stringstream ss(line);
		std::string word;
		std::string changed_line;
		ss >> word;//读入原序列
		int ori_num = std::stoi(word);
		int new_num = newNumCnt;
		char buff[20];
		changed_line += itoa(newNumCnt, buff, 16);
		changed_line += ' ';
		newNumCnt += 0xd;
		h = insert(ori_num, new_num, h);
		while (ss >> word) {
			if (word == "GOTO" || word == "GOSUB") {
				changed_line += word;
				changed_line += ' ';
				ss >> word;
				changed_line += itoa(map(atoi(word.c_str()), h), buff, 16);
			}
			else {
				changed_line += word;
				changed_line += ' ';
			}
		}
		proc.push_back(changed_line);
	}
	for (const auto &str : proc) {
		std::cout << str << std::endl;
	}
}


你可能感兴趣的:(数据结构与算法分析c语言描述,使得第一条语句从F处开始)