如何在输入耗尽之前从输入复制到输出? [英] How do I copy from input to output until input is exhausted?

查看:85
本文介绍了如何在输入耗尽之前从输入复制到输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我曾经参加过面试的编程测试。我不是一名优秀的考生。我的解决方案如下,我只是在寻找一些关于为什么我的解决方案不被接受的见解:



我需要在VB.Net中编写一个程序来复制从输入到输出直到输入耗尽。程序应该使用(并且不实现)下面描述的方法 GetData() PutData()



方法 GetData()提供输入。它的功能原型是:

 公共 功能 GetData( ByRef  Buf() As   Char 作为 整数 





它返回放入 Buf 的字符数,该值小于或等于512.这个数字因呼叫而异。如果为0,则表示输入已用完。



方法 PutData()接受输出。它的功能原型是:

 公共  Sub  PutData( ByVal  Buf() as   Char  ByVal 计算作为 整数





Buf <输出 Count 字符/ code>。 Count必须表示 Buf 中包含的字符数,并且每次调用都是512,但是最后一次。对于最后一次通话,它可能小于512(甚至0)。



以上是我曾经接受过的一次编程测试。



我提交了以下代码:



我在下面的代码中写了这个测试的答案,以及招聘经理说我错了因为我做了假设:

 ' 此代码假设GetData()始终返回512,直到 
' 最后数据读取块;只有这样才会返回512或更少。
Sub Main()
Dim buffer 作为 字符()= 字符 512 ){}
Dim count As 整数 = 0
while (InlineAssignHelper(count,GetData(buffer)))<> 0
PutData(缓冲区,计数)
结束 while
结束 Sub

' 此方法仅用于确保我们可以分配
' GetData在while循环的每次迭代中计数,而
' 同时检测是否已返回零字节。
私有 函数 InlineAssignHelper( Of T)( ByRef target 作为 T, ByVal As T)作为 T
target = value
返回
结束 功能





招聘经理说我错了做出假设。任何人都可以告诉我为什么这段代码没有回答编程测试,或者这位面试官是一个光顾的冲洗袋,不知道他在说什么F $ CK?



让我感到震惊的是招聘经理说的话似乎有一个序列。但是,我不明白...如果我有一个 GetData()方法本质上是一个黑盒子读者,我怎么知道,先验,数据块序列?



我个人认为这个编程测试是由一个虚拟的,一个适合所有人的招聘经理写的,他不知道关于编码的事情,但刚刚被他们的老板交给了一张纸而老板说,这里给每个人都应用这种不可能通过的测试。



Brian

解决方案

CK他在谈论什么?



绊倒我的是什么似乎是招聘经理所说的序列。但是,我不明白...如果我有一个 GetData()方法本质上是一个黑盒子读者,我怎么知道,先验,数据块序列?



我个人认为这个编程测试是由一个虚拟的,一个适合所有人的招聘经理写的,他不知道关于编码的事情,但刚刚被他们的老板交给了一张纸而老板说,这里给每个人都应用这种不可能通过的测试。



Brian


仔细阅读规范后,这并不像听起来那么简单。



GetData 可以(并且将)从 0 512 。只有返回值 0 表示数据结束;任何其他值可以跟随更多数据。



PutData 必须为每个电话传递512个字符,除了最后一个。



如果没有 PutData 的限制,评论中的代码将是(几乎*)完美。但是,有了这个限制,你的代码就不符合规范。



例如, GetData 可能会返回 250 512 110 1 0 。为确保 PutData 在除最后一个调用之外的每个调用中都收到512个字符,您需要第二个缓冲区来处理读取的下溢和溢出。



这样的东西应该有效:

  Sub  Main() 
Dim buffer As Char ()= 字符 511 ) {}
Dim count 作为 整数 = 0

Dim tempBuffer 作为 字符()= 字符 511 ){}
Dim tempCount As 整数
Dim toCopy As 整数

执行
tempCount = GetData(tempBuffer)
如果 tempCount<> ; 0 然后
' < span class =code-comment>复制所有读取的数据,
' 或足以填充主缓冲区:
toCopy = Math.Min(tempCount,buffer.Length - count)
Array.Copy(tempBuffer, 0 ,缓冲区,计数,toCopy)
count + = toCopy

如果 count = buffer.Length 然后
' 我们填充了主缓冲区。
' 放入数据并清除缓冲区:
PutData (缓冲区,计数)
count = 0

如果 tempCount> toCopy 然后
' 我们阅读更多数据我们可以放入主缓冲区。
' 将剩余数据复制到主缓冲区。
' (这将始终少于512个字符,因此无需检查第二次溢出。)
Array.Copy(tempBuffer,toCopy,buffer, 0 ,tempCount - toCopy)
count = tempCount - toCopy
结束 如果
结束 如果
结束 如果
循环 tempCount<> 0

如果 count<> 0 然后
' < span class =code-comment>我们还有一些缓冲数据,所以把它写入输出:
PutData(缓冲区,计数)
结束 如果
结束 Sub







*差不多,因为你的缓冲区是一个字符太大。 VB.NET数组是使用数组的上限声明的,而不是元素的数量,所以你的数组应声明为 New Char(511){}


基本上,你对这个测试的质量持怀疑态度。但这取决于如何看待问题。让我们看看...



使用一些黑匣子系统没有任何问题,但只有表现一致。但是,如果你分析它,你会发现理论上可以在输入流上有这样的接口。奇怪的是,如果返回值返回小于512,则输入可能会或可能不会耗尽。然而,你必须阅读直到它为止。那么输出怎么样?



如果看一下输出,它可能看起来很矛盾。如果您尝试直截了当,可以面对以下情况。假设您从输入中收到的字符少于512个。规则说它并不意味着它已经筋疲力尽。您可以获得任意数量少于512块的数据,但不能为0;描述的界面允许系统为您完成。如果您将此块发送到输出,即使输入尚未耗尽,您也无法再发送。



因此,正确的解决方案是累积数据在中间存储中,从输入中添加更多数据,直到获得512字节或更多。当它发生时,你应该发送正好512个字节并将其余部分留在这个中间存储器中,从输入中添加数据,直到你有足够的发送215或输入耗尽。



当然,给定的系统是一个非常差的设计的例子。但是你没有采用它,这可能是这次测试的主要目的。您需要能够发现必须与之交互的可用系统中的问题,并解决此类问题。您必须弄清楚解决方案是否可行,拒绝理论上无法解决的系统,并考虑使用可以使用的系统。



-SA

The following is for a programming test I was once given for a job interview. I am not a good test-taker. My solution is below, and I am just looking for some insights as to why my solution was not accepted:

I need to write a program in VB.Net which copies from input to output until the input is exhausted. The program should use (and NOT implement) the methods GetData() and PutData() described below.

The method GetData() provides input. Its function prototype is:

Public Function GetData(ByRef Buf() As Char) As Integer



It returns the number of characters placed into Buf, a value less than or equal to 512. This number varies from one call to the next. If it is 0, input is exhausted.

The method PutData() accepts output. Its function prototype is:

Public Sub PutData(ByVal Buf() as Char, ByVal Count As Integer)



It writes Countcharacters to output from Buf. Count must represent the number of characters contained in Buf and be 512 for every call but the last. It may be less than 512 (even 0) for the last call only.

The above is a programming test I was once given as a interview.

I submitted the following code:

I wrote the code below for the answer to this test, and the hiring manager said I was wrong because I was making assumptions:

' This code is assuming that GetData() always returns 512 until the very 
' last data block is read; only then is 512 or less returned.
Sub Main()
    Dim buffer As Char() = New Char(512) {}
    Dim count As Integer = 0
    While (InlineAssignHelper(count, GetData(buffer))) <> 0
        PutData(buffer, count)
    End While
End Sub

' This method is only here to ensure we can assign the result of 
' GetData to count with each iteration of the while loop, while 
' at the same time, detect whether zero bytes have been returned.
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
    target = value
    Return value
End Function



The hiring manager said i was wrong for making assumptions. Can anyone please tell me why this code does not answer the programming test, or is this interviewer being a patronizing douche bag that doesn't know what the F$CK he is talking about?

What's tripping me up is that there seems to be a 'sequence' involved in what the hiring manager is saying. However, I don't get it...if I have a GetData() method that is essentially a black-box "reader", how can I know, a priori, the data block sequence?

Personally i think this programming test was written by a dummy, a one-size-fits-all hiring manager who doesn't know a thing about coding but just was handed some piece of paper by their boss and the boss is saying, "here give everyone that applies this impossible-to-pass test."

Brian

解决方案

CK he is talking about?

What's tripping me up is that there seems to be a 'sequence' involved in what the hiring manager is saying. However, I don't get it...if I have a GetData() method that is essentially a black-box "reader", how can I know, a priori, the data block sequence?

Personally i think this programming test was written by a dummy, a one-size-fits-all hiring manager who doesn't know a thing about coding but just was handed some piece of paper by their boss and the boss is saying, "here give everyone that applies this impossible-to-pass test."

Brian


After a closer reading of the specification, this isn't quite as simple as it sounds.

GetData can (and will) return any number from 0 to 512. Only a return value of 0 indicates the end of the data; any other value could be followed by more data.

PutData must be passed exactly 512 characters for every call except that last.

Without the restriction on PutData, your code in the comments would be (almost*) perfect. However, with that restriction in place, your code doesn't meet the specification.

For example, GetData might return 250, 512, 110, 1, 0. To ensure that PutData received 512 characters on every call except the last, you would need a second buffer to deal with both underflow and overflow on the reads.

Something like this should work:

Sub Main()
    Dim buffer As Char() = New Char(511) {}
    Dim count As Integer = 0

    Dim tempBuffer As Char() = New Char(511) {}
    Dim tempCount As Integer
    Dim toCopy As Integer

    Do
        tempCount = GetData(tempBuffer)
        If tempCount <> 0 Then
            ' Either copy all of the data read,
            ' or enough to fill the main buffer:
            toCopy = Math.Min(tempCount, buffer.Length - count)
            Array.Copy(tempBuffer, 0, buffer, count, toCopy)
            count += toCopy

            If count = buffer.Length Then
                ' We've filled the main buffer.
                ' Put the data and clear the buffer:
                PutData(buffer, count)
                count = 0

                If tempCount > toCopy Then
                    ' We read more data that we could fit in the main buffer.
                    ' Copy the remaining data to the main buffer.
                    ' (This will always be less than 512 characters, so no need to check for a second overflow.)
                    Array.Copy(tempBuffer, toCopy, buffer, 0, tempCount - toCopy)
                    count = tempCount - toCopy
                End If
            End If
        End If
    Loop While tempCount <> 0

    If count <> 0 Then
        ' We have some buffered data left, so write it to the output:
        PutData(buffer, count)
    End If
End Sub




* Almost, because your buffer is one character too large. VB.NET arrays are declared using the upper-bound of the array, not the number of elements, so your array should be declared as New Char(511){}.


Basically, you are right in your suspicious thoughts about the quality of this test. But it depends on how to look at the problem. Let's see…

There is nothing wrong with using some black box systems, but only if behave consistently. However, if you analyze it, you will see that it is theoretically possible to have such interface on input stream. The weird point is that if the return value returns less then 512, the input may or may not be exhausted. Nevertheless, you have to read until it's 0. How about output then?

If you look at the output, it may look as a contradiction. If you try straightforward approach, you can face the following situation. Let's say, you receive less then 512 characters from input. The rules say that it does not mean that it is exhausted. You can get any number of less-then-512 chunks of data, but not 0; the described interface allows the system to do that for you. If you send this chunk to output, you loose the ability to send anymore, even if input is not yet exhausted.

So, the right solution would be to accumulate data in intermediate storage, adding more data from input, until you get 512 bytes or more. When it happens, you should send exactly 512 bytes and leave the rest in this intermediate storage, adding data from input, until you have enough to send 215 or input is exhausted.

Certainly, the given system is an example of really poor design. But you failed to adopt it, which could be the main purpose for this test. You need to be able to spot problems in available systems you have to interface with, and work around such problems. You have to figure out if the solution is possible or not, reject systems which are theoretically impossible to work around, and consider using those which can be used.

—SA


这篇关于如何在输入耗尽之前从输入复制到输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆