编程难巧试题之整束

收录一些有兴趣的试题

1`

题目:求1+2+…+n,

要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。


- (int)counting:(int)n
{
    static int result = 0;
    
    result += n--;
    
    n && [self counting:n];
    
    return result;
}


原理:

n > 0 在c中表示为真, && 运算符在左表达式为真后会继续判右表达式是否为真,若左表达示为假(即n  == 0)时则不再判断右表达式。以此实现递归算法。



2`


题目: 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。


- (void)Reverse:(char*)array beginIndex:(int)beginIndex endIndex:(int)endIndex
{
    for (; beginIndex < endIndex; beginIndex++, endIndex--)
    {
        char temp = array[endIndex];
        array[endIndex] = array[beginIndex];
        array[beginIndex] = temp;
    }
}

- (void)shift:(char *)array offset:(int)offset // offset > 0右移, 反之左移
{
    int length = (int)strlen(array);
    
    offset %= length;
    
    if (array == NULL || offset == 0)
    {
        return;
    }
    
    if (offset < 0)
    {
        offset += length;
    }
    
    [self Reverse:array beginIndex:0 endIndex:(length - offset - 1) ];
    [self Reverse:array beginIndex:(length - offset) endIndex:(length - 1) ];
    [self Reverse:array beginIndex:0 endIndex:(length - 1) ];
}


原理:

abcd ef  将字符串abcdef分解

dcba fe 分别逆置两段字符串

efabcd 逆置整个字符串

以此实现右移n位字符, 左移则调整移动位n为字符串长度length - n 



3` 打印杨辉三角,要求数字对齐, 三角形为等腰三角形

public static void print_yanghui(int n)
{
	if (n < 1)
	{
		return;
	}
	
	int space = 0;
	ArrayList<ArrayList<BigDecimal> > list = new ArrayList<ArrayList<BigDecimal>> (); // 使用BigDecimal以免数值溢出
	
	for (int i = 1; i <= n; i++) // 计算杨辉三角中各数
	{
		ArrayList<BigDecimal> l = new ArrayList<BigDecimal>();
		
		for (int j = 1; j <= i; j++)
		{
			if (j == 1 || j == i)
			{
				l.add(BigDecimal.ONE);
			}
			else
			{
				l.add(list.get(i - 2).get(j - 2).add(list.get(i - 2).get(j - 1) ) ); // 里面的add是BigDecimal相加,外面的则是list增加元素
			}
			
			if (i == n && l.get(j - 1).toString().length() > space) // 记录数值中最大数的长度作为间距,这里可以直接选中最后一行中间的元素计算
			{
				space = l.get(j - 1).toString().length();
			}
		}
		
		list.add(l);
	}
	
	space += space % 2; // 间距统一为双数
	
	for (int i = 0 ; i < n ; i++)
	{
		for (int j = 0; j < (n - i) * space; j++) // 打印前置空位
		{
			System.out.print(" ");
		}
		
		for (int k = 0; k <= i; k++)
		{
			BigDecimal element = list.get(i).get(k);
			System.out.print(element); // 打印数值
			
			// 计算偏移量, 调速每个数值后要打印的空格数
			int offset = 0;
			offset += space; // 加上间距
			offset += space - element.toString().length(); // 加上本数值占位未使用的部分
			offset += element.toString().length() / 2; // 加上本数值的居中偏移量, 对应下一数值的居中偏移量
			
			if (k < i)
			{
				offset -= list.get(i).get(k + 1).toString().length() / 2; // 为下一数值预留居中中偏移量
			}
			
			for (int l = 0; l < offset; l++) // 打印间距空位
			{
				System.out.print(" ");
			}
		}
		
		System.out.println(); // 换行
	}
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值