笔试题练习(二)

本文介绍了一种不使用额外空间进行链表元素交叉归并的方法,并探讨了字节对齐原理及其应用,同时提供了插入排序的具体实现,还讨论了字符串截取函数的设计,最后通过C++代码展示了位字段的应用。

1、不使用额外空间,将 A,B两链表的元素交叉归并

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->/**
*
*
@authorphinecos
*
@since2009-05-19
*
*/
publicclassLinkList
{
privatestaticclassNode
{
//内部节点类
privateintvalue;//节点值
Nodenext;//下一个节点
publicNode(intvalue)
{
this.value=value;
this.next=null;
}
publicNode(intvalue,Nodenext)
{
this.value=value;
this.next=next;
}
publicintgetValue()
{
returnvalue;
}
publicvoidsetValue(intvalue)
{
this.value=value;
}
publicNodegetNext()
{
returnnext;
}
publicvoidsetNext(Nodenext)
{
this.next=next;
}
}
privateNodehead;//头节点

publicLinkList()
{
this.head=null;
}
publicLinkList(LinkListrhs)
{
Nodecurrent
=rhs.head;
while(current!=null)
{
this.add(current.value);
current
=current.next;
}
}
publicbooleanadd(intnum)
{
//以递增方式增加节点到链表头部
NodenewNode=newNode(num);
if(this.head==null)
{
//第一个节点
this.head=newNode;
}
else
{
Nodepre
=null,current=this.head;
while(current!=null&&current.value<num)
{
//找到合适的插入位置
pre=current;
current
=current.next;
}
//插入新节点
pre.next=newNode;
newNode.next
=current;
}
returntrue;
}

publicbooleanremove(Nodenode)
{
//删除节点
Nodepre=null,current=this.head;
if(node==this.head)
{
//要删除的是头节点
this.head=this.head.next;
}
else
{
while(current!=node)
{
pre
=current;
current
=current.next;
}
pre.next
=current.next;
}
current
=null;
returntrue;
}

publicbooleanmerge(LinkListrhs)
{
//和另一个链表合并(不使用额外空间),以当前链表为基准
booleanresult=false;
Nodep1,p2,p2Pre;
p2Pre
=null;
p1
=this.head;
p2
=rhs.head;
while((p1!=null)&&(p2!=null))
{
if(p1.value<p2.value)
{
p1
=p1.next;
}
elseif(p1.value>=p2.value)
{
p2Pre
=p2;
p2
=p2.next;
rhs.remove(p2Pre);
this.add(p2Pre.value);
}
}
while(p2!=null)
{
p2Pre
=p2;
rhs.remove(p2Pre);
this.add(p2Pre.value);
p2
=p2.next;
}
returnresult;
}
@Override
publicStringtoString()
{
StringBuildersb
=newStringBuilder();
Nodecurrent
=this.head;
while(current!=null)
{
sb.append(current.value);
current
=current.next;
}
returnsb.toString();
}

publicstaticvoidmain(String[]args)
{
LinkListlist1
=newLinkList();
list1.add(
1);
list1.add(
7);
list1.add(
5);
list1.add(
4);
list1.add(
3);
LinkListlist2
=newLinkList();
list2.add(
2);
list2.add(
4);
list2.add(
8);

list1.merge(list2);

System.out.println(list1);
System.out.println(list2);
}
}

2,字节对齐

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include<iostream>
usingnamespacestd;

structA
{
shorta1;
shorta2;
shorta3;
};
structB
{
longa1;
shorta2;
};
structC
{
inta1;
shorta2;
chara3;
};
intmain()
{
cout
<<sizeof(A)<<endl;
cout
<<sizeof(B)<<endl;
cout
<<sizeof(C)<<endl;
return0;
}

输出:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->6
8
8

结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对齐,则a1,a2,a3都取2字节对齐,则sizeof(A)为6,其也是2的整数倍.

B中a1为4字节对齐,a2为2字节对齐,结构体默认对齐参数为8,则a1取4字节对齐,a2取2字节对齐,结构体大小6字节,6不为4的整数倍,补空字节,增到8时,符合所有条件,则sizeof(B)为8。

C中补空字节,结构体大小加到8时,是4的倍数,符合条件.

根据上述原理可做如下实验:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->structC
{
inti;//4个字节
shorts;//2个字节
charc;//1个字节
longa4;//4个字节
};

此时sizeof(C)输出12,因为结构体大小填充字节到12时,是4的倍数,符合条件。

那如果想抛弃掉字节对齐呢,如何做呢?只需要加入下面语句即可

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#pragmapack(1)

3,插入排序

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->importjava.util.*;
classInsertSort
{
Listal
=null;
publicInsertSort(intnum,intmod)
{
al
=newArrayList(num);
Randomrand
=newRandom();
System.out.println(
"TheArrayListSortBefore:");
for(inti=0;i<num;i++)
{
al.add(
newInteger(Math.abs(rand.nextInt())%mod+1));
System.out.println(
"al["+i+"]="+al.get(i));
}
}
publicvoidsortList()
{
IntegertempInt;
intMaxSize=1;
for(inti=1;i<al.size();i++)
{
tempInt
=(Integer)al.remove(i);//待插入的数据
if(tempInt.intValue()>=((Integer)al.get(MaxSize-1)).intValue())
{
al.add(MaxSize,tempInt);
//插入
MaxSize++;
System.out.println(al.toString());
}
else
{
//比结尾数据小,找到插入位置
for(intj=0;j<MaxSize;j++)
{
if(((Integer)al.get(j)).intValue()>=tempInt.intValue())
{
al.add(j,tempInt);
MaxSize
++;
System.out.println(al.toString());
break;
}
}
}
}
System.out.println(
"TheArrayListSortAfter:");
for(inti=0;i<al.size();i++)
{
System.out.println(
"al["+i+"]="+al.get(i));
}
}
publicstaticvoidmain(String[]args)
{
InsertSortis
=newInsertSort(10,100);
is.sortList();
}
}

4,编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如ABC”4,应该截为AB”,输入ABCDEF”6,应该输出为ABC”而不是ABC+汉的半个

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->importjava.util.ArrayList;
importjava.util.List;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;

/**
*
*
@authorphinecos
*
@since2009-05-19
*
*/
publicclassTest
{
publicstaticbooleanisChinense(Stringstr)
{
//是否中文
booleanresult=false;
//U+4e00~U+9FB0
Patternp1=Pattern.compile("[/u4E00-/u9FB0]");
Matcherm
=p1.matcher(str);
if(m.matches())
{
result
=true;
}
returnresult;
}
publicstaticList<String>splitString(StringstrInfo,intn)
{
List
<String>result=newArrayList<String>();
StringstrTmp;
intcount=0;
StringBuildersb
=newStringBuilder();
for(inti=0;i<strInfo.length();++i)
{
strTmp
=strInfo.substring(i,i+1);

if(count<n)
{
if(isChinense(strTmp))
{
//是中文
count+=2;
sb.append(strTmp);

}
else
{
++count;
sb.append(strTmp);
}
}
elseif(count>n)
{
sb.deleteCharAt(sb.length()
-1);
i
-=2;
count
=0;
result.add(sb.toString());
sb.delete(
0,sb.length());
}
else
{
count
=0;
result.add(sb.toString());
sb.delete(
0,sb.length());
--i;
}
}

returnresult;
}
publicstaticvoidmain(String[]args)
{
StringstrInfo
="中国,我是phinecos爱好java";
List
<String>result=splitString(strInfo,6);
for(Strings:result)
{
System.out.println(s);
}

}
}

5,

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include<iostream>
usingnamespacestd;

structbit
{
inta:3;
intb:2;
intc:3;
};
intmain(intargc,char*argv[])
{
bits;
char*c=(char*)&s;
inta=2;
a
+=2;
*c=0x99;
cout
<<s.a<<endl<<s.b<<endl<<s.c<<endl;
return0;
}

输出:

1

-1

-4

解答:int a:3的意思是a占3个bit依次类推

c指向s,*c=0x99后,c指向的值变为0x99,即100 11 001故a=1 b= -1 c= -4

因为最高位为符号位

100(算术右移)

=>1111 1111 1111 1100 = -4

11(算术右移)

=>1111 1111 1111 1111 = -1

001(算术右移)

=>0000 0000 0000 0001 = 1

最高位是1,就向左补齐1,最高位是0,就补0,然后按补码看,

如100,最高位是1,按32位补齐成1111 1111 1111 1100 ,这是补码,还原成原码,减一取反为100,负的100,即-4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值