编程小练习(5)

重复的电话号码

查找一个文件中重复的电话号码,所有的大小写字母按照手机九宫格映射到数字,其余字符不考虑,将重复的号码还原后升序输出到接口的文件中,号码小于12位。

#include <stdlib.h>
#include "PhoneBookProcess.h"
#include <map>
#include <string>
#include <fstream>
#include <iostream>
#include <stdio.h>
/*
功能: 检查是否有两个或多个公司拥有相同的电话号码,并统计输出
输入参数: inFileName  - 包含个性电话号码个数与列表的源文件名
          outFileName - 输出统计重复号码的结果的目标文件名
输出参数: 无
返回: 0 - 成功
       1 - 其它各种错误,如文件不存在
*/
long long str2num(std::string str)
{
	int dict[] = {
		2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9
	};
	long long ago = 0;
	int t = 0;
	for(unsigned i = 0; i < str.length(); ++i) {
		if( str[i] >= '0' && str[i] <= '9')
			t = str[i] - '0';
		else if(str[i] >= 'a' && str[i] <= 'z')
			t = dict[str[i]-'a'];
		else if(str[i] >= 'A' && str[i] <='Z')
			t = dict[str[i]-'A'];
		else
			continue;
		ago = ago * 10 + t;
	}
	return ago;
}

int PhoneBookProcess(const char *inFileName,const char *outFileName) 
{
	std::ifstream inf(inFileName);
	std::ofstream outf(outFileName);
	if(!inf || !outf) return 1;

	std::map<long long,int> m;
	std::string str;
	long long ago;
	inf >> str; // 跳过首行
	while(inf) {
		inf >> str;
		ago = str2num(str);
		if (ago == 0) continue;
		if(m.count(ago) == 0) {
			m[ago] = 1;
		} else {
			m[ago]++;
		}
		str = "";
	}	

	std::map<long long, int>::iterator it;
	bool isDup = false;
	for(it = m.begin(); it != m.end(); ++it){
		if(it->second > 1){
			outf << it->first << " " << it->second << "\n";
			isDup = true;
		}
	}
	
	if(!isDup){
		outf << "No duplicates.\n";
	}
	return 0;
}

字节流解析

对 char 字节数组中,指定位置,指定长度,解析出数字。

#include "OJ.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void toBitChars(unsigned char a[], char *p, unsigned int len) {
    int i, j, k, length;
    char temp[10] = {'\0'};
    for(i = 0;i < len; i++) {
        itoa((int)a[i],temp,2);
        length = strlen(temp);
        if(length < 8) {
            k = 7;
            for(j = length - 1; j >= 0; --j)
                temp[k--] = temp[j];
            for(j = 0; j < 8 - length; ++j)
                temp[j] = '0';
        }
        j = 0;
        while(temp[j]) *p++ = temp[j++];
    }
}

unsigned int calValue(char *p, int len) {
    unsigned int sum = 0;
    for(int i = 0; i < len; ++i)
        sum = sum*2 + p[i] - '0';
    return sum;
}

void Decode(unsigned int uiIutputLen, unsigned char aInputByte[],
        unsigned int uiElementNum, ELEMENT_STRU astElement[]) {
    if (uiIutputLen == 0 || uiElementNum == 0 || !aInputByte || !astElement)
        return;
    char buffer[1000];
    toBitChars(aInputByte, buffer, uiIutputLen);
    int offset = 0;
    for(int i = 0; i < uiElementNum; ++i) {
        int len = astElement[i].uiElementLength;
        astElement[i].uiElementValue = calValue(buffer + offset, len);
        offset += len;
    }
    return;
}

英文金曲大赛

从输入的字符串中获取打分,去掉最高最低分后算平均分,按照制定格式输出。

#include "OJ.h"
#include <stdio.h>
#include <string.h> 
#include <algorithm>
void GetResult(char* pInput[], int Num, char *pResult)
{
	int a[7]={0};
	char name[30]="";
	char line[40]="";
	float sum = 9, avg=0;
	int sumhe=0,max,min;
      for(int i=0;i<Num;i++)
	  {
		  sscanf(pInput[i],"%d %d %d %d %d %d %d %s",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],name);
		  std::sort(a, a+7);
		  sum = 0;
		  for(int j = 1; j < 6; ++j){
			sum += a[j];
		  }
		  avg = sum / 5;
		  sprintf(line,"%s %4.2f",name,avg);
		  sprintf(pResult,"%s%s\n\0",pResult,line);
	  }
	    int length=strlen(pResult);
        pResult[length-1]='\0';
	return;
} 		

渊子赛马

判断渊子是否可以赢,已知自己的马可以跑过敌方马的的个数,类似田忌赛马,合理安排后判断是否可以赢。

#include "OJ.h"
#include <algorithm>
/*
功能:判断yuanzi 的马是否会赢?yuanzi 的马赢了,返回 YES. 否则返回 NO
输入参数:
unsigned int num: 赛马的数量;   (1<= num <=1000)
unsigned int * speed_yz: yuanzi 的马的速度;
unsigned int * speed_op: 对手的马的速度;
返回值:
		char * 型 的字符串,yuanzi 的马赢了,返回 YES. 否则返回 NO;
*/

char * IsYuanziWin(unsigned int num, unsigned int * speed_yz, unsigned int * speed_op)
{
	std::sort(speed_yz, speed_yz + num);
	std::sort(speed_op, speed_op + num);
	int i = 0, j = 0, count = 0;
	while(i < num && j < num) {
		if(speed_yz[i] <= speed_op[j]) {
			++i;
		} else {
			++i; 
			++j;
			++count;
		}
	}
	if(count > num / 2)
		return "YES";
	else
		return "NO";
}

【中级】双链表基本操作

插入删除读取,还有大数相加。

#include <stdlib.h>

#define null 0
#define MAXSIZE 50

struct strlnode
{
	int data;
	struct strlnode *plast;
	struct strlnode *pnext;
};

void create(struct strlnode **p, int x)  /*创建双链表(表头节点)*/
{
	struct strlnode *q;
	q = (struct strlnode *)malloc(sizeof(struct strlnode));
	q->data = x;
	q->plast = null;
	q->pnext = null;
	*p = q;
	return;
}

void insertnode(struct strlnode **p, int i, int x) /* 在链表第i个位置插入数据等于x的节点 */
{
	/* 代码在这里实现 */
	if(*p == null) return;

	struct strlnode *a = *p;
	int len = 1;
	while(a->pnext != null){
		a=a->pnext;
		++len;
	}
	if(i > len || i < -1) return;

	struct strlnode* v = (struct strlnode*)malloc(sizeof(struct strlnode));
	v->data = x;

	if(i == 0){
		v->pnext = *p;
		v->plast = null;
		(*p)->plast = v;
		*p = v;
	} else if(i == len) {
		a->pnext = v;
		v->plast = a;
		v->pnext = null;
	} else {
		a = *p;
		for(int j = 0; j < i-1; ++j){
			a = a->pnext;
		}
		v->pnext = a->pnext;
		v->plast = a;
		a->pnext = v;
		v->pnext->plast = v;
	}
}

void deletenode(struct strlnode **p, int i) /* 删除链表中第i个节点 */
{
	/* 代码在这里实现 */
	if(*p == null) return;

	struct strlnode *a = *p, *tmp;
	int len = 1;
	while(a->pnext != null){
		a=a->pnext;
		++len;
	}
	if(i > len-1 || i < -1) return;

	if(i == 0) {
		tmp = (*p)->pnext;
		tmp->plast = null;
		free(*p);
		*p = tmp;
	} else if(i == len-1) {
		a->plast->pnext = null;
		free(a);
	} else {
		a = *p;
		for(int j = 0; j < i; ++j) {
			a = a->pnext;
		}
		a->plast->pnext = a->pnext;
		a->pnext->plast = a->plast;
		free(a);
	}
}

int getnodenum(struct strlnode **p)  /*获取链表中节点个数*/
{
	int nodenum = 0;
	/* 代码在这里实现 */
	struct strlnode *a = *p;
	while(a) {
		a = a->pnext;
		++nodenum;
	}
	return nodenum;
}

void bignumberplus(struct strlnode **plus, struct strlnode **p, struct strlnode **q) /* 使用链表实现大整数相加 */
{
	/* 代码在这里实现 */
	int lenp = getnodenum(p);
	int lenq = getnodenum(q);
	int lenBig = lenp > lenq ? lenp : lenq;
	struct strlnode *pt = *p, *qt = *q;
	int a[1000] = {0}, b[1000] = {0};

	for(int i = lenp - 1; i >= 0; --i){
		a[i] = pt->data;
		pt = pt->pnext;
	}
	for(int i = lenq - 1; i >= 0; --i) {
		b[i] = qt->data;
		qt = qt->pnext;
	}

	for(int i = 0; i < lenBig; ++i) {
		a[i] += b[i];
		if(a[i] >= 10){
			a[i+1] += a[i] / 10;
			a[i] %= 10;
		}
	}
	if(a[lenBig] > 0){
		++lenBig;
	}

	(*plus)->data = a[lenBig-1];
	int i = lenBig-2, j = 1;
	while(i >= 0) {
		insertnode(plus, j++, a[i--]);
	}
}


void readtolnode(struct strlnode **p, int *a, int size)  /* 将数组写入链表中,链表中的数据的先后顺序和数组中的顺序要保持一致 */
{
	int j = 0;
	int data = 0;
	struct strlnode *s = *p;

	s->data = *(a + (size-1));

	for(j = 2; j < (size+1); j++)
	{
		data = *(a + (size-j));
		insertnode(p, 0, data);
	}

	return;
}


void writetosqlist(int *a, struct strlnode *p)  /* 将链表写入数组中,数组中的数据的先后顺序和链表中的顺序要保持一致 */
{
	int j = 0;
	struct strlnode *s = p;

	while(s != null)
	{
		*(a + j) = s->data;
		s = s->pnext;
		j++;
	}

	return;
}

矩阵相乘2

求连个矩阵相乘后的结果

#include "oj.h"
/*
功能: 矩阵相乘
输入: MatrixA,MatrixB
输出: MatrixC
返回: 0
*/
int matrix(int **MatrixA, int **MatrixB, int **MatrixC, int N)
{
	int *A = (int *)MatrixA, *B=(int *)MatrixB, *C=(int *)MatrixC;
	for(int i = 0; i < N; ++i) {
		for(int j=0; j < N; ++j) {
			C[i * N + j] = 0; 
			for(int k = 0; k < N; ++k){
				C[i * N + j] += A[i * N + k] * B[k * N + j];
			}
		}
	}
	return 0;
}

Home+Work

每一行的两个元素依次为做完这一份试卷所需的时间、做完这份试卷的价值,求可以取得的最大值。

#include "OJ.h"
#include <algorithm>
#include <vector>

/*
输入: nPapers表示试卷的数目(1≤Papers≤20),nRemain表示剩余的时间(1≤nRemain≤10000),
      paper[][2]是一个Papers*2的数组,

每一行的两个元素依次为做完这一份试卷所需的时间、做完这份试卷的价值

输出: *pMaxValue为获得的最大价值
返回:
0:异常
1:计算成功返回
*/
struct perTimeValue {
	double per;
	int time;
	int value;
	bool operator <(const perTimeValue &k) const{
	  return per > k.per;
	}
};

int GetMaxValue(int nPapers, int nRemain, int paper[][2], double* pMaxValue)
{
    std::vector<perTimeValue> v;
    perTimeValue a;
    for (int i = 0; i < nPapers; ++i){
        a.per = paper[i][1] * 1.0 / paper[i][0];
        a.time = paper[i][0];
        a.value = paper[i][1];
        v.push_back(a);
    }
	std::sort(v.begin(), v.end());
    *pMaxValue = 0;
	std::vector<perTimeValue>::iterator it;
	for(it = v.begin(); it != v.end(); ++it){
		if(nRemain > it->time){
			*pMaxValue += it->value;
			nRemain -= it->time;
		} else {
			*pMaxValue += it->per * nRemain;
			break;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值