利用select函數(shù)可以完成非阻塞通信,它可以在用戶(hù)指定的時(shí)間內(nèi)監(jiān)聽(tīng)一些句柄(文件描述符?)(一個(gè)句柄就是你給一個(gè)文件,設(shè)備,套接字(socket)或管道的一個(gè)名字, 以便幫助你記住你正處理的名字, 并隱藏某些緩存等的復(fù)雜性。),當(dāng)readfds或writefds中映象的文件可讀或可寫(xiě)或超時(shí),本次select()就結(jié)束返回。程序員利用一組系統(tǒng)提供的宏在select()結(jié)束時(shí)便可判斷哪一文件可讀或可寫(xiě)。
。
函數(shù)原型:
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
ndfs:select監(jiān)視的文件句柄數(shù),視進(jìn)程中打開(kāi)的文件數(shù)而定,一般設(shè)為你要監(jiān)視各文件
中的最大文件號(hào)加一。
readfds:select監(jiān)視的可讀文件句柄集合。
writefds: select監(jiān)視的可寫(xiě)文件句柄集合。
exceptfds:select監(jiān)視的異常文件句柄集合。
timeout:本次select()的超時(shí)結(jié)束時(shí)間。
函數(shù)返回值:
0表示超時(shí)
-1表示出錯(cuò)
正數(shù)表示文件可讀或可寫(xiě)
相關(guān)的宏:
FD_ZERO(fd_set *fdset):清空f(shuō)dset與所有文件句柄的聯(lián)系。
FD_SET(int fd, fd_set *fdset):建立文件句柄fd與fdset的聯(lián)系。
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd與fdset的聯(lián)系。
FD_ISSET(int fd, fd_set *fdset):檢查fdset聯(lián)系的文件句柄fd是否可讀寫(xiě),當(dāng)>0表示可讀寫(xiě)。
select只能監(jiān)聽(tīng)文件描述符(file descriptors),文件指針是不行的。通過(guò)int fileno(FILE* fp)函數(shù)可以完成文件指針到文件描述符的轉(zhuǎn)換。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
int main(){
int fno = fileno(stdin);
// 得到sdtin的文件描述符
fd_set fdR;
struct timeval timeout = {.tv_sec = 10, .tv_usec = 0};
FD_ZERO(&fdR);
FD_SET(fno, &fdR);
char str[64];
int goOn = 1;
while(goOn){
printf("goOning
\n");
switch(select(fno + 1, &fdR, NULL, NULL, &timeout)){
case -1:
printf("select fail\n");
goOn = 0;
break;
case 0:
printf("select end\n");
goOn = 0;
break;
default:
scanf("%s", str);
printf("str=%s\n", str);
}
}
}
代碼片段1:在指定時(shí)間內(nèi)讀取stdin的數(shù)據(jù)。
代碼片段2:服務(wù)器在一定時(shí)間內(nèi)接收子節(jié)點(diǎn)發(fā)來(lái)的數(shù)據(jù)報(bào)。
int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
…

…

fd_set fdR;
struct timeval timeout = {tv_sec:10, tv_usec:0};// 等待接收一定時(shí)間之后結(jié)束
int goOn = 1;
FD_ZERO(&fdR);
FD_SET(sockfd, &fdR);
while(goOn){
switch(select(sockfd + 1, &fdR, NULL, NULL, &timeout)){
case -1:
printf("select fail\n");
goOn = 0;
break;
case 0:
printf("select timeout\n");
goOn = 0;
break;
default:
// 正常情況,讀取信息
if((numbytes = recvfrom(sockfd, &cdt, sizeof(cdt), 0,
(struct sockaddr *)&their_addr, &addr_len)) == -1){
printf("recvfrom fail\n");
}
}
參閱:
http://www.tuicool.com/articles/Rfeaie
posted @
2014-03-26 16:25 小鼠標(biāo) 閱讀(3990) |
評(píng)論 (0) |
編輯 收藏
脫氧核糖核酸即常說(shuō)的DNA,是一類(lèi)帶有遺傳信息的生物大分子。它由4種主要的脫氧核苷酸(dAMP、dGMP、dCMT和dTMP)通過(guò)磷酸二酯鍵連接而成。這4種核苷酸可以分別記為:A、G、C、T。
DNA攜帶的遺傳信息可以用形如:AGGTCGACTCCA.... 的串來(lái)表示。DNA在轉(zhuǎn)錄復(fù)制的過(guò)程中可能會(huì)發(fā)生隨機(jī)的偏差,這才最終造就了生物的多樣性。
為了簡(jiǎn)化問(wèn)題,我們假設(shè),DNA在復(fù)制的時(shí)候可能出現(xiàn)的偏差是(理論上,對(duì)每個(gè)堿基被復(fù)制時(shí),都可能出現(xiàn)偏差):
1. 漏掉某個(gè)脫氧核苷酸。例如把 AGGT 復(fù)制成為:AGT
2. 錯(cuò)碼,例如把 AGGT 復(fù)制成了:AGCT
3. 重碼,例如把 AGGT 復(fù)制成了:AAGGT
如果某DNA串a(chǎn),最少要經(jīng)過(guò) n 次出錯(cuò),才能變?yōu)镈NA串b,則稱(chēng)這兩個(gè)DNA串的距離為 n。
例如:AGGTCATATTCC 與 CGGTCATATTC 的距離為 2
你的任務(wù)是:編寫(xiě)程序,找到兩個(gè)DNA串的距離。
【輸入、輸出格式要求】
用戶(hù)先輸入整數(shù)n(n<100),表示接下來(lái)有2n行數(shù)據(jù)。
接下來(lái)輸入的2n行每2行表示一組要比對(duì)的DNA。(每行數(shù)據(jù)長(zhǎng)度<10000)
程序則輸出n行,表示這n組DNA的距離。
例如:用戶(hù)輸入:
3
AGCTAAGGCCTT
AGCTAAGGCCT
AGCTAAGGCCTT
AGGCTAAGGCCTT
AGCTAAGGCCTT
AGCTTAAGGCTT
則程序應(yīng)輸出:
1
1
2
結(jié)題思路:參閱百度百科http://baike.baidu.com/view/2020247.htm
代碼如下:
import java.util.*;



public class Main
{
static String instr0;
static String instr1;
public static void main(String[] args)

{
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
sc.nextLine();

for(int ii = 0; ii < N; ii++)
{
instr0 = sc.nextLine();
instr1 = sc.nextLine();
int rs = pro();
System.out.println(rs);
}
}

static int pro()
{
int[][] dis = new int[instr0.length()][instr1.length()];
for(int i = 0; i < instr0.length(); i++)
dis[i][0] = i;
for(int j = 0; j < instr1.length(); j++)
dis[0][j] = j;

for(int i = 1; i < instr0.length(); i++)
{

for(int j = 1; j < instr1.length(); j++)
{
int cost = 0;
if(instr0.charAt(i) != instr1.charAt(j))
cost = 1;
dis[i][j] = min3(dis[i - 1][j] + 1, dis[i][j - 1] + 1,
dis[i - 1][j - 1] + cost);
}
}
return dis[instr0.length() - 1][instr1.length() - 1];
}

static int min3(int a, int b, int c)
{
return Math.min(Math.min(a, b), c);
}

}
posted @
2013-07-09 19:26 小鼠標(biāo) 閱讀(404) |
評(píng)論 (0) |
編輯 收藏
在很多軟件中,輸入拼音的首寫(xiě)字母就可以快速定位到某個(gè)詞條。比如,在鐵路售票軟件中,輸入: “bj”就可以定位到“北京”。怎樣在自己的軟件中實(shí)現(xiàn)這個(gè)功能呢?問(wèn)題的關(guān)鍵在于:對(duì)每個(gè)漢字必須能計(jì)算出它的拼音首字母。
GB2312漢字編碼方式中,一級(jí)漢字的3755個(gè)是按照拼音順序排列的。我們可以利用這個(gè)特征,對(duì)常用漢字求拼音首字母。
GB2312編碼方案對(duì)每個(gè)漢字采用兩個(gè)字節(jié)表示。第一個(gè)字節(jié)為區(qū)號(hào),第二個(gè)字節(jié)為區(qū)中的偏移號(hào)。為了能與已有的ASCII編碼兼容(中西文混排),區(qū)號(hào)和偏移編號(hào)都從0xA1開(kāi)始。
我們只要找到拼音a,b,c,...x,y,z 每個(gè)字母所對(duì)應(yīng)的GB2312編碼的第一個(gè)漢字,就可以定位所有一級(jí)漢字的拼音首字母了(不考慮多音字的情況)。下面這個(gè)表給出了前述信息。請(qǐng)你利用該表編寫(xiě)程序,求出常用漢字的拼音首字母。
a 啊 B0A1
b 芭 B0C5
c 擦 B2C1
d 搭 B4EE
e 蛾 B6EA
f 發(fā) B7A2
g 噶 B8C1
h 哈 B9FE
j 擊 BBF7
k 喀 BFA6
l 垃 C0AC
m 媽 C2E8
n 拿 C4C3
o 哦 C5B6
p 啪 C5BE
q 期 C6DA
r 然 C8BB
s 撒 C8F6
t 塌 CBFA
w 挖 CDDA
x 昔 CEF4
y 壓 D1B9
z 匝 D4D1
【輸入、輸出格式要求】
用戶(hù)先輸入一個(gè)整數(shù)n (n<100),表示接下來(lái)將有n行文本。接著輸入n行中文串(每個(gè)串不超過(guò)50個(gè)漢字)。
程序則輸出n行,每行內(nèi)容為用戶(hù)輸入的對(duì)應(yīng)行的漢字的拼音首字母。
字母間不留空格,全部使用大寫(xiě)字母。
例如:
用戶(hù)輸入:
3
大家愛(ài)科學(xué)
北京天安門(mén)廣場(chǎng)
軟件大賽
則程序輸出:
DJAKX
BJTAMGC
RJDS
結(jié)題思路:
C語(yǔ)言中的一個(gè)漢字占兩個(gè)字節(jié)(兩個(gè)char),我們只需把這兩個(gè)字節(jié)對(duì)應(yīng)的int型數(shù)字算出來(lái),然后到編碼表里去比較即可。計(jì)算該數(shù)字時(shí)要用到
移位,與,或等位運(yùn)算操作。
代碼如下:
#include<stdio.h>
#include<string.h>
int N;
char str[200];

void pro()
{
for(int i = 0; i < strlen(str) - 1; )

{
char c0 = str[i++];
char c1 = str[i++];
int t = (int)c0 << 8;//得到高八位
t = t | (0x000000ff & (int)c1);//得到低八位
t &= 0x0000ffff;//去掉負(fù)號(hào)

if(t >= 0xB0A1 && t < 0xB0C5)
{
printf("A");
}
else if(t < 0xB2C1)
printf("B");
else if(t < 0xB4EE)
printf("C");
else if(t < 0xB6EA)
printf("D");
else if(t < 0xB7A2)
printf("E");
else if(t < 0xB8C1)
printf("F");
else if(t < 0xB9FE)
printf("G");
else if(t < 0xBBF7)
printf("H");
else if(t < 0xBFA6)
printf("J");
else if(t < 0xC0AC)
printf("K");
else if(t < 0xC2E8)
printf("L");
else if(t < 0xC4C3)
printf("M");
else if(t < 0xC5B6)
printf("N");
else if(t < 0xC5BE)
printf("O");
else if(t < 0xC6DA)
printf("P");
else if(t < 0xC8BB)
printf("Q");
else if(t < 0xC8F6)
printf("R");
else if(t < 0xCBFA)
printf("S");
else if(t < 0xCDDA)
printf("T");
else if(t < 0xCEF4)
printf("W");
else if(t < 0xD1B9)
printf("X");
else if(t < 0xD4D1)
printf("Y");
else
printf("Z");
}
printf("\n");
}

int main()


{
scanf("%d", &N);
getchar();
for(int i = 0; i < N; i++)

{
gets(str);
pro();
}
//getchar();
}

posted @
2013-07-09 11:04 小鼠標(biāo) 閱讀(1218) |
評(píng)論 (0) |
編輯 收藏
1949年的國(guó)慶節(jié)(10月1日)是星期六。
今年(2012)的國(guó)慶節(jié)是星期一。
那么,從建國(guó)到現(xiàn)在,有幾次國(guó)慶節(jié)正好是星期日呢?
不多說(shuō)了,直接上代碼:
import java.util.*;



public class Main
{
public static void main(String[] args)

{
int count = 0;
int weekd = 5;

for(int i = 1950; i < 2013; i++)
{
int y = 365;
if(isRN(i))
y++;
weekd = (weekd + y) % 7;

if(weekd == 6)
{
count++;
System.out.println("i=" + i);
}
}
System.out.println("count=" + count);
}

static boolean isRN(int y)
{
if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
return true;
return false;
}

}
posted @
2013-07-09 09:22 小鼠標(biāo) 閱讀(206) |
評(píng)論 (0) |
編輯 收藏
截取JDK文檔中的一部分,感覺(jué)這些東西我以后會(huì)用到。
字符類(lèi) |
[abc] |
a、b 或 c(簡(jiǎn)單類(lèi)) |
[^abc] |
任何字符,除了 a、b 或 c(否定) |
[a-zA-Z] |
a 到 z 或 A 到 Z,兩頭的字母包括在內(nèi)(范圍) |
[a-d[m-p]] |
a 到 d 或 m 到 p:[a-dm-p](并集) |
[a-z&&[def]] |
d、e 或 f(交集) |
[a-z&&[^bc]] |
a 到 z,除了 b 和 c:[ad-z](減去) |
[a-z&&[^m-p]] |
a 到 z,而非 m 到 p:[a-lq-z](減去) |
Greedy 數(shù)量詞 |
X? |
X,一次或一次也沒(méi)有 |
X* |
X,零次或多次 |
X+ |
X,一次或多次 |
X{n} |
X,恰好 n 次 |
X{n,} |
X,至少 n 次 |
X{n,m} |
X,至少 n 次,但是不超過(guò) m 次 |
這些目前來(lái)說(shuō)夠用啦。
posted @
2013-07-09 09:00 小鼠標(biāo) 閱讀(180) |
評(píng)論 (0) |
編輯 收藏
【編程題】(滿分21分)
Excel是最常用的辦公軟件。每個(gè)單元格都有唯一的地址表示。比如:第12行第4列表示為:“D12”,第5行第255列表示為“IU5”。
事實(shí)上,Excel提供了兩種地址表示方法,還有一種表示法叫做RC格式地址。 第12行第4列表示為:“R12C4”,第5行第255列表示為“R5C255”。
你的任務(wù)是:編寫(xiě)程序,實(shí)現(xiàn)從RC地址格式到常規(guī)地址格式的轉(zhuǎn)換。
【輸入、輸出格式要求】
用戶(hù)先輸入一個(gè)整數(shù)n(n<100),表示接下來(lái)有n行輸入數(shù)據(jù)。
接著輸入的n行數(shù)據(jù)是RC格式的Excel單元格地址表示法。
程序則輸出n行數(shù)據(jù),每行是轉(zhuǎn)換后的常規(guī)地址表示法。
例如:用戶(hù)輸入:
2
R12C4
R5C255
則程序應(yīng)該輸出:
D12
IU5
結(jié)題思路:字符串處理,26進(jìn)制轉(zhuǎn)換。特別注意26要被轉(zhuǎn)換成Z,因?yàn)锳表示的是1而不是0。
代碼如下:
(代碼實(shí)現(xiàn)了兩種格式的互換問(wèn)題)
import java.util.*;



public class Main
{
static int N;
static String instr1;
public static void main(String[] args)

{
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
sc.nextLine();

for(int i = 0; i < N; i++)
{
instr1 = sc.nextLine();

if(isRC(instr1))
{
toAN();
}

else
{
toRC();
}
}
}

static void toRC()
{

/**//*
* D12-->R12C4
*/
int i = 0;
int numc = 0;

while(Character.isLetter(instr1.charAt(i)))
{
numc *= 26;
numc += instr1.charAt(i) - 'A' + 1;
i++;
}
int numr = Integer.parseInt(instr1.substring(i));
System.out.println("R" + numr + "C" + numc);
}

static void toAN()
{

/**//*
* R12C4-->D12
*/
StringBuffer sbuf = new StringBuffer();
String[] strs = instr1.split("[RC]");//正則式很有趣
int numc = Integer.parseInt(strs[2]);

while(numc > 0)
{
char c = (char)((numc - 1) % 26 + 'A');//num - 1,避免26被轉(zhuǎn)換為A
sbuf.append(c);
numc = (numc - 1) / 26;//num - 1,避免26被轉(zhuǎn)換為AZ
}
System.out.println(sbuf.reverse() + strs[1]);
}

static boolean isRC(String instr)
{
int count = 0;
boolean isnumbg = false;

for(int i = 0; i < instr.length(); )
{

if(Character.isDigit(instr.charAt(i)))
{

if(isnumbg)
{
i++;
}

else
{
isnumbg = true;
count++;
i++;
}
}

else
{

if(isnumbg)
{
isnumbg = false;
}
i++;
}
}
if(count == 2)
return true;
return false;
}
}
posted @
2013-07-07 20:27 小鼠標(biāo) 閱讀(505) |
評(píng)論 (0) |
編輯 收藏
某少年宮引進(jìn)了一批機(jī)器人小車(chē)??梢越邮茴A(yù)先輸入的指令,按指令行動(dòng)。小車(chē)的基本動(dòng)作很簡(jiǎn)單,只有3種:左轉(zhuǎn)(記為L(zhǎng)),右轉(zhuǎn)(記為R),向前走若干厘米(直接記數(shù)字)。
例如,我們可以對(duì)小車(chē)輸入如下的指令:
15L10R5LRR10R20
則,小車(chē)先直行15厘米,左轉(zhuǎn),再走10厘米,再右轉(zhuǎn),...
不難看出,對(duì)于此指令串,小車(chē)又回到了出發(fā)地。
你的任務(wù)是:編寫(xiě)程序,由用戶(hù)輸入指令,程序輸出每條指令執(zhí)行后小車(chē)位置與指令執(zhí)行前小車(chē)位置的直線距離。
【輸入、輸出格式要求】
用戶(hù)先輸入一個(gè)整數(shù)n(n<100),表示接下來(lái)將有n條指令。
接下來(lái)輸入n條指令。每條指令只由L、R和數(shù)字組成(數(shù)字是0~100之間的整數(shù))
每條指令的長(zhǎng)度不超過(guò)256個(gè)字符。
程序則輸出n行結(jié)果。
每條結(jié)果表示小車(chē)執(zhí)行相應(yīng)的指令前后位置的直線距離。要求四舍五入到小數(shù)后2位。
例如:用戶(hù)輸入:
5
L100R50R10
3LLL5RR4L12
LL
100R
5L5L5L5
則程序輸出:
102.96
9.06
0.00
100.00
0.00
結(jié)題思路:
模擬機(jī)器人行走即可,用數(shù)字表示機(jī)器人的方向,向上為0,向右為1,下為2,左為3。設(shè)初始狀態(tài)機(jī)器人方向?yàn)?,則遇到R就將當(dāng)前方向加1,遇到L將當(dāng)前方向減1。x軸向右增大,y軸向上增大。
代碼如下:
import java.util.*;


public class Main
{
static int x = 0;
static int y = 0;
static int nowdir = 0;
static int N;
static String instr;
public static void main(String[] args)

{
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
sc.nextLine();

for(int i = 0; i < N; i++)
{
instr = sc.nextLine();
x = 0;
y = 0;
nowdir = 0;
pro();
double dis0 = Math.sqrt(x * x + y * y);
System.out.printf("%.2f\n", dis0);
}
}

static void pro()
{
boolean isnumbg = false;
int numbgp = 0;
instr = instr + "#";

for(int i = 0; i < instr.length();)
{

if(Character.isDigit(instr.charAt(i)))
{

if(isnumbg)
{
i++;
continue;
}

else
{
numbgp = i++;
isnumbg = true;
}
}

else
{

if(isnumbg)
{
isnumbg = false;
String str1 = instr.substring(numbgp, i);
int dis = Integer.parseInt(str1);

if(nowdir == 0)
{
y += dis;
}

else if(nowdir == 2)
{
y -= dis;
}

else if(nowdir == 1)
{
x += dis;
}
else
x -= dis;
}

else
{
char c = instr.charAt(i);

if(c == 'R')
{
nowdir = (nowdir + 1) % 4;
}

else if(c == 'L')
{
nowdir = (nowdir + 3) % 4;
}
i++;
}
}
}
}
}
posted @
2013-07-07 17:16 小鼠標(biāo) 閱讀(649) |
評(píng)論 (0) |
編輯 收藏
看這個(gè)算式:
☆☆☆ + ☆☆☆ = ☆☆☆
如果每個(gè)五角星代表 1 ~ 9 的不同的數(shù)字。
這個(gè)算式有多少種可能的正確填寫(xiě)方法?
173 + 286 = 459
295 + 173 = 468
173 + 295 = 468
183 + 492 = 675
以上都是正確的填寫(xiě)法!
注意:
111 + 222 = 333 是錯(cuò)誤的填寫(xiě)法!
因?yàn)槊總€(gè)數(shù)字必須是不同的!
也就是說(shuō):1~9中的所有數(shù)字,每個(gè)必須出現(xiàn)且僅出現(xiàn)一次!
結(jié)題思路:
排列1~9,寫(xiě)出符合條件的結(jié)果。
代碼如下:


public class Main
{

static int bs[] =
{1, 2, 3, 4, 5, 6, 7, 8, 9};
static int count = 0;
public static void main(String[] args)

{
count = 0;
DFS(0);
System.out.println("count=" + count);
}

static void DFS(int nowp)
{

if(nowp == bs.length)
{
int n1 = bs[0] * 100 + bs[1] * 10 + bs[2];
int n2 = bs[3] * 100 + bs[4] * 10 + bs[5];
int n3 = bs[6] * 100 + bs[7] * 10 + bs[8];

if(n1 + n2 == n3)
{
System.out.println(n1 + " + " + n2 + " = " + n3);
count++;
}
}

else
{

for(int i = nowp; i < bs.length; i++)
{
swap(nowp, i);
DFS(nowp + 1);
swap(nowp, i);
}
}
}

static void swap(int a, int b)
{
int t = bs[a];
bs[a] = bs[b];
bs[b] = t;
}
}
posted @
2013-07-07 16:08 小鼠標(biāo) 閱讀(290) |
評(píng)論 (0) |
編輯 收藏